Closing my message box and root window in python 3.6 - python-3.x

import statements
import from tkinter import *
import tkinter.simpledialog
import tkinter.messagebox
from tkinter import ttk
from time import strftime
now = strftime( "%x %Z %X")
Setting window
root=Tk()
root.title("ON TOP OF THE WORLD")
canvas= Canvas(root, width=350, height=250)
canvas.pack()
photo=PhotoImage(file='/Users/m/Desktop/TOTW.gif')
canvas.create_image(0, 0, anchor = NW, image=photo)
Welcome User
tkinter.messagebox.showinfo("Hello,today is", now)
ask user
name=tkinter.simpledialog.askstring("name","What is your name?" )
input process
output = "Hello, %s! May the only place you find yourself today is on top of the world !" %name
show output
tkinter.messagebox.showinfo(now, output)
CLOSE
def on_closing():
if tkinter.messagebox.askokcancel("Quit", "Do you want to quit?"):
root.destroy()
root.protocol(on_closing)
root.mainloop()
I need help in closing or ending this dialogue box

You could take two other approaches to this, one being quit() and simply ending the code all together, or using frames in tkinter and calling a different frame whether it says close or comes up blank. It would be able to cover everything already there

Related

How to Display Progress bar from Windows shell in TKinter?

I am running an "Any file type to PDF Convertor" code using python. When I convert Word files to PDF, it displays a progress bar in the Windows Shell like so:
But I want this progress bar to be displayed inside the Tkinter window.
Is there a way to do this?
Because when I run it as an exe, I cannot let "-w" stay there otherwise the program crashes.
Here's the code:
from tkinter import *
from PIL import Image
from tkinter import filedialog
def buttonclick():
root.filename=filedialog.askopenfilename(initialdir="Pictures", title="Select File", filetypes=(("All Files","*.*"),("PNG Files","*.png"),("JPG Files","*.jpg")))
try:
locus=root.filename.split(".")
dest=str(locus[0]+".pdf")
if str(locus[-1])=="docx":
from docx2pdf import convert
'''
import ttk as t
progressbar = t.Progressbar(orient=HORIZONTAL, length=200, mode='determinate')
progressbar.pack(side="bottom")
'''
convert(root.filename,dest)
#progressbar.start()
notifier=Label(root, text="File converted to PDF successfully!", fg="green", bg="#BFDFFF").pack()
elif str(locus[-1])=="pdf":
notifier=Label(root, text="PDF file Selected! Choose another file type.", fg="black", bg="#BFDFFF").pack()
elif str(locus[-1])=="":
notifier=Label(root, text="Please select a file!", fg="black", bg="#BFDFFF").pack()
else:
imge=Image.open(root.filename)
im1 = imge.convert('RGB')
im1.save(dest)
notifier=Label(root, text="File converted to PDF successfully!", fg="green", bg="#BFDFFF").pack()
except:
notifier=Label(root, text="An unexpected error occured!", fg="red", bg="#BFDFFF").pack()
root=Tk()
root.title("Any File to PDF Convertor")
root.config(bg="#BFDFFF")
root.geometry("300x200")
root.iconbitmap("D:\Coding\MyIcon.ico")
convert=Button(root, text="Select File",font=("Helvetica", 20), bg="#85FF97",command=lambda: buttonclick())
convert.pack(pady=20)
root.mainloop()
Why not try a progress bar widget. Check out this code. I did not bother adapting my solution to your case since you have accepted the answer:
from tkinter import *
from tkinter.ttk import *
import os
root = Tk()
# I set the length and maximum as shown to demonstrate the process in the
# proceeding function. Pay attention to the increment r
progress = Progressbar(root, orient = HORIZONTAL,
length = 200/5, maximum=200/5, mode = 'determinate')
# Function
def my_func():
t=0
r= 1/5
for i in range(200):
print(i) #whatever function interests you
t=t+r
progress['value'] = t
root.update_idletasks()
progress.pack()
# Button
Button(root, text = 'Start', command = bar).pack(pady = 10)
mainloop()

How do I display a message before closing the tkinter window?

A message is required to be shown just before closing the tkinter window on the click of a close button added to the window.
lab = Label(window,text = 'thank you')
lab.grid()
window.destroy()
I used the above code to do so, but the window gets closed before the message is being displayed
Can I have the solution for this?
You can either use this:
from tkinter import Tk
import tkinter.messagebox as msgbox
def display_msg():
msgbox.showinfo(title='', message='Thank You')
root.destroy()
root = Tk()
root.protocol('WM_DELETE_WINDOW', display_msg)
root.mainloop()
which will show You a messagebox before closing,
or if You want to display a widget use this:
from tkinter import Tk, Label
def display_msg():
msg = Label(root, text='Thank You!')
msg.pack()
root.after(3000, root.quit)
root = Tk()
root.protocol('WM_DELETE_WINDOW', display_msg)
root.mainloop()
When You protocol root with 'WM_DELETE_WINDOM' You can make it execute a function when You try to close the window.
In the first example it will just show an infobox.
In the second example it will wait for 3 seconds (3000 miliseconds) and then destroy the root

darken the whole tkinter window

I'm programming a game sa my graduation project in school. Once the manager closes the game, I want the other users to have a pop up that the game is ended and a button to click on in order to continue.
I want the whole window (with all the widgets) to get darker (not totally black but darker). Everything besides the pop up and the "continue" button
Enyone has a clue what I can do? I searched on the Internet and found nothing :/
Not able to use ImageGrab on linux, here is my solution:
import tkinter as tk
import numpy as np
import time
import pyscreenshot as ImageGrab
from PIL import Image, ImageTk
def grab(widget):
box = (widget.winfo_rootx(), widget.winfo_rooty(), widget.winfo_rootx()+widget.winfo_width(), widget.winfo_rooty()+widget.winfo_height())
grab = ImageGrab.grab(bbox=box)
return grab
def darken(widget):
widget.overlay = ImageTk.PhotoImage(Image.fromarray(np.asanyarray(grab(widget))//2))
cvs = tk.Canvas(widget, width=widget.winfo_width(), height=widget.winfo_height())
cvs.place(x=0,y=0)
cvs.create_image(0, 0, anchor='nw', image=widget.overlay)
return cvs
root = tk.Tk()
def apply_dark():
cvs = darken(root)
b = tk.Button(root, text='Ok')
def d():
cvs.destroy()
b.destroy()
b.config(command=d)
b.place(x=50, y=10)
tk.Label(root, text='Label1').grid(row=0, column=0)
tk.Label(root, text='Label2').grid(row=0, column=1)
tk.Button(root, text='Button1').grid(row=1, column=0)
tk.Button(root, text='Darken', command=apply_dark).grid(row=1, column=1)
root.mainloop()
Fiddle around with this code. Of course this is in fact just a quick bodge (non-reliable, inefficient), but still - works for me.
Hope that's helpful!

stop ttk.Entry() from reading keyboard

Environment: macOS Catalina, Python 3.7.4, Tcl/Tk 8.6.9, VSC 1.39.1
I have a situation where I am using a bar/qr code scanner to provide a string to a ttk.Entry() method, which then fires off a function.
The reader is seen by the OS as an HID keyboard, so the text from the QR code is received by the ttk.Entry() widget that I give focus to during code execution. I have bound the widget to the key because the scanner sends a cr/lf at the end of the text string, which works as needed.
However, I am running into an issue where if the qr code lingers over the scanner too long it will rescan the qr code and the widget receives the qr code text again, which then causes it to be processed again.
I have tried disabling the ttk.Entry() in the function, deleting the widget contents, and removing focus to no avail. The behavior I'm seeing is occurring even though the widget is disabled and does not have focus, it is still getting input and executing the function again if the scanner rescans the qr code while the function is executing.
In this first example, I simply tried to disable the widget, but that doesn't work. The widget still gets the later scans while in the function.
# test-ttk-entry1.py
import time
import tkinter as tk
from tkinter import StringVar, ttk
root = tk.Tk()
def print_text(event):
global kbEntry
textValue = kbEntry.get()
kbEntry.configure(state="disabled")
time.sleep(2) # Add in a delay to allow for repeat scan
print(textValue)
time.sleep(2) # Add in a delay to allow for repeat scan
kbEntry.configure(state="active")
kbText = StringVar()
kbEntry = ttk.Entry(root, width=10, textvariable=kbText)
kbEntry.bind("<Return>", print_text)
kbEntry.pack()
kbEntry.focus_set()
root.mainloop()
The second attempt was to disable the entry widget and upon making it active again delete the text in the field.
# test-ttk-entry2.py
import time
import tkinter as tk
from tkinter import END, StringVar, ttk
root = tk.Tk()
def print_text(event):
global kbEntry
textValue = kbEntry.get()
kbEntry.delete(0, END)
kbEntry.configure(state="disabled")
time.sleep(2) # Add in a delay to allow for repeat scan
print(textValue)
time.sleep(2) # Add in a delay to allow for repeat scan
kbEntry.configure(state="active")
kbEntry.delete(0, END)
kbText = StringVar()
kbEntry = ttk.Entry(root, width=10, textvariable=kbText)
kbEntry.bind("<Return>", print_text)
kbEntry.pack()
kbEntry.focus_set()
root.mainloop()
And finally, I was reading about taking focus from a widget and giving focus to the root window, so I added that in and it still prints multiple times to the console like there is a keyboard buffer being read by the ttk.Entry() widget. The weird thing is it seems like widgets don't normally respond to any calls to methods when they are disabled, but it appears the ttk.Entry() widget's properties/attributes (excuse me if my OOP terms are not correct) can be manipulated while disabled.
# test-ttk-entry2.py
import time
import tkinter as tk
from tkinter import END, StringVar, ttk
root = tk.Tk()
def print_text(event):
global kbEntry
textValue = kbEntry.get()
kbEntry.delete(0, END)
kbEntry.configure(state="disabled")
root.focus_set()
time.sleep(2) # Add in a delay to allow for repeat scan
print(textValue)
time.sleep(2) # Add in a delay to allow for repeat scan
kbEntry.configure(state="active")
kbEntry.delete(0, END)
kbEntry.focus_set()
kbText = StringVar()
kbEntry = ttk.Entry(root, width=10, textvariable=kbText)
kbEntry.bind("<Return>", print_text)
kbEntry.pack()
kbEntry.focus_set()
root.mainloop()
So how can I prevent the ttk.Entry() widget from accepting any input from the HID/keyboard device while my function is executing?
Since I am unable to find a way to temporarily disable the .Entry() widget programmatically to keep it from reading successive inputs, I have come up with this solution:
# test-ttk-entry2.py
import time
import tkinter as tk
from tkinter import END, StringVar, ttk
root = tk.Tk()
tempStr = "" # Global temporary string variable to trip repeated scans
def print_text(event):
global tempStr
textValue = kbEntry.get()
if tempStr == textValue:
kbEntry.delete(0, END)
print ("Duplicate scan")
return
tempStr = textValue
kbEntry.delete(0, END)
print(textValue)
time.sleep(3) # Simulate the time it takes for the function to complete
kbEntry = ttk.Entry(root, width=10)
kbEntry.bind("<Return>", print_text)
kbEntry.grid(row=0, column=0, padx=10, pady=10)
kbEntry.focus_set()
root.mainloop()

tkinter Button does not open new window

I’m experiencing problems with tkinter.
I have code that is meant to open a new window on button press, but the window does not open.
Here’s my code:
Main Module
#!/usr/bin/python
#encoding: latin-1
import tkinter
import ce
#window config
window = tkinter.Tk() #create window
window.title("BBDOassist") #set title
window.geometry("750x500") #set size
…
# buttons
button_ce = tkinter.Button(window, text="CE Evaluation", command="ce.run()")
button_ce.pack()
window.mainloop() #draw the window and start
’CE’ Module
#!/usr/bin/python
#encoding: latin-1
import tkinter
…
def run():
#window config
window = tkinter.Tk() #create window
window.title("BBDOassist - CE Evaluation") #set title
window.geometry("750x500") #set size
…
window.mainloop() #draw the window and start
You have at least two problems
First, you must give the command attribute a reference to a function. You are passing it a string. A string is useless. You need to change your button definition to this:
button_ce = tkinter.Button(window, text="CE Evaluation", command=ce.run)
Second, if you want to create additional windows then you need to create instances of Toplevel rather than Tk. A tkinter program needs exactly one instance of Tk, and you need to call mainloop exactly once.
Change run to look like this (and remove the call to mainloop inside run):
def run():
#window config
window = tkinter.Toplevel()
...

Resources