Posts: 741
Threads: 120
Joined: Dec 2017
Hi,
I'm getting pretty confused, reading about modal windows in tKinter.
I thought it would be simple.
I have an existing app,where users make a selection in a listbox, and go on from there.
However, as an extra service, I would like this selection to trigger a pop-up TopLevel window,
with a rather large amout of text.
That is easy.
BUT, I would like this TopLevel to be modal, so the user has to close it before moving on.
I had hoped that adding some parameter to "topWindow = Toplevel(height=500, width=200)"
would do the trick, but how ?
thanks,
Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Posts: 1,067
Threads: 111
Joined: Sep 2019
Oct-15-2023, 09:06 AM
(This post was last modified: Oct-15-2023, 09:06 AM by menator01.)
If you're using TopLevel could you not just use the withdraw and deiconify functions?
I have an example on the site. I will search and post the link.
Not the example I was looking for but, same principle.
https://python-forum.io/thread-26925-pos...#pid114781
Another quick example of toplevel window
import tkinter as tk
class TopWindow:
def __init__(self, root):
self.root = root
self.window = tk.Toplevel(None)
label = tk.Label(self.window, text='This is a top level window.')
label.pack()
btn = tk.Button(self.window, text='Close Me', command=self.close)
btn.pack()
self.window.protocol('WM_DELETE_WINDOW', self.close)
def close(self):
self.window.destroy()
self.root.deiconify()
class MainWindow:
def __init__(self, parent):
self.parent = parent
label = tk.Label(parent, text='The Main Window')
label.pack()
btn = tk.Button(parent, text='Open Window', command=self.openme)
btn.pack()
def openme(self):
self.parent.withdraw()
TopWindow(self.parent)
root = tk.Tk()
MainWindow(root)
root.mainloop()
Posts: 741
Threads: 120
Joined: Dec 2017
(Oct-15-2023, 09:06 AM)menator01 Wrote: If you're using TopLevel could you not just use the withdraw and deiconify functions? Thanks and agreed.
Seems to be a lot of hassle for something I thought to be simple.
I'll try it.
Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Posts: 4,686
Threads: 73
Joined: Jan 2018
Have you tried the grab_set() method?
Posts: 1,067
Threads: 111
Joined: Sep 2019
One more example that I found here. I used the example at the bottom of the page.
https://stackoverflow.com/questions/1005...dialog-box
import tkinter as tk
from tkinter.simpledialog import Dialog
class MyDialog(Dialog):
def __init__(self, parent, **kwargs):
Dialog.__init__(self, parent, **kwargs)
def body(self, parent):
label = tk.Label(self, text='Can hold tkinter widgets such as label, listbox, etc...', wraplength=300, justify='left', anchor='w')
label.pack()
def validate(self):
return 1
def apply(self):
pass
class Window:
def __init__(self, parent):
self.parent = parent
btn = tk.Button(parent, text='Click Me', command=self.opendialog)
btn.pack()
def opendialog(self):
MyDialog(self.parent)
root = tk.Tk()
Window(root)
root.mainloop()
Posts: 11,969
Threads: 481
Joined: Sep 2016
Oct-15-2023, 01:11 PM
(This post was last modified: Oct-15-2023, 01:11 PM by Larz60+.)
check out grab_set as mentioned above by Griboullis
for example, see: https://www.pythontutorial.net/tkinter/t...-toplevel/
Posts: 6,576
Threads: 19
Joined: Feb 2020
Oct-15-2023, 03:06 PM
(This post was last modified: Oct-15-2023, 03:07 PM by deanhystad.)
If all you want to do is display a block of text and an ok button, look at tkinter.dialog.Dialog, the parent class for tkinter common dialogs.
import tkinter as tk
from tkinter.dialog import Dialog, DIALOG_ICON
class Window(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.title("Basic Dialog Demo")
tk.Button(
self, text='Push me! Push me! Push me!', command=self.opendialog
).pack(padx=80, pady=(100, 10))
def opendialog(self):
with open(__file__, "r") as file:
text = file.read()
Dialog(
self,
title="Popup Dialog",
text=text,
bitmap=DIALOG_ICON,
default=0,
strings=("OK",)
)
print("Dialog closed.")
Window().mainloop()
Posts: 741
Threads: 120
Joined: Dec 2017
The problem with this forum is that you get so may valid responses.
Now I need to try them all.
Won't tell which one suits best, not to make anyone jealous.
thx,
Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Posts: 741
Threads: 120
Joined: Dec 2017
Oct-16-2023, 03:08 PM
(This post was last modified: Oct-16-2023, 03:08 PM by DPaul.)
FYI
The good news is, that I now have a nice & shining modal TopLevel window!
Thanks,
Paul
edit: showed it to a user today, he loved it !
menator01 likes this post
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Posts: 6,576
Threads: 19
Joined: Feb 2020
Calling grab_set() makes a TopLevel window modal, but it does not make it act like a dialog. A dialog window blocks execution of the caller, which makes it easy to write code that uses values from the dialog. In Menator's first example, this function returns immediately.
def opendialog(self):
MyDialog(self.parent) # This does not block.
print("Hello") This is fine for showing a message, but would not work for Yes/Now window, a color picker, a file picker, a anything that returns a value that is important window.
Menator's second example does block here:
def opendialog(self):
MyDialog(self.parent) # Will wait for program to close.
print("Hello") This is a characteristic of being a dialog, not being modal. Dialogs run their own mainloop(). This blocks the code that opened the dialog.
|