Re: tk bug in wait_visibility?
Bryan Oakley <[email protected]> Fri, 14 Feb 2020 08:47:50 -0600
| Newsgroups | gmane.comp.python.tkinter |
|---|---|
| Message-ID | <CAKypQnzHK2UOn-cJVE_Cm3O+Si-5611S2Lg2yeJA5C4cT=+M3g@mail.gmail.com> |
--===============0457166853886333434== Content-Type: multipart/alternative; boundary="000000000000038387059e8a4b7b" --000000000000038387059e8a4b7b Content-Type: text/plain; charset="UTF-8" wait_visibility waits for a *change in the visibility,* it doesn't just wait for the window to be visible. If it's already visible, wait_visibility will wait for it to be invisible. The geometry method doesn't affect the visibility state (unless you move the window off-screen perhaps) which is why your code ends up waiting forever. If you want to wait for a window to be visible, you should first check to see if it is already visible. Otherwise you'll end up waiting for it to become invisible. On Fri, Feb 14, 2020 at 7:48 AM Vasilis Vlachoudis < [email protected]> wrote: > In some dialogs I wanted to restore the size from the last time it was > opened > therefore, before calling the wait_window I have > > self.wait_visibility() > self.geometry(...restore...) #<<< the geometry setting will not work > if it is not visible > self.wait_window() > > If something happens during the filling of the dialog information I show a > messagebox. > The messagebox is triggering the event loop, which displays also the dialog > If the dialog is displayed then the execution gets stuck in the > "wait_visibility", > and when the user closes the dialog, the execution proceeds to the > wait_window > which causes an exception since the window do not longer exits. > > I think it is a tk bug, that the wait_visibility waits despite the window > is visible. > The only way to cure it is to add a check "if self.winfo_ismapped()" > > Example: > > > import tkinter as tk > import tkinter.messagebox as messagebox > > error = True > > class Dialog(tk.Toplevel): > width = 320 > height = 240 > > def __init__(self, master, *args): > super().__init__(master, *args) > self.transient(master) > > self.b = tk.Button(self, text="Close", command=self.close) > self.b.pack() > > if error: > messagebox.showerror("Error", > "Something happened", > parent=self) > > #if not self.winfo_ismapped(): self.wait_visibility() > self.wait_visibility() > if Dialog.width>0: > self.geometry(f"{Dialog.width}x{Dialog.height}") > self.wait_window() > > def close(self): > # save size... and destroy... > self.destroy() > > > root = tk.Tk() > dlg = Dialog(root) > _______________________________________________ > Tkinter-discuss mailing list > [email protected] > https://mail.python.org/mailman/listinfo/tkinter-discuss > --000000000000038387059e8a4b7b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><font face=3D"monospace">wait_visibility</font> waits for = a <i>change in the visibility,</i> it doesn't just wait for the window = to be visible. If it's already visible, <font face=3D"monospace">wait_v= isibility</font> will wait for it to be invisible. The <font face=3D"monosp= ace">geometry</font> method doesn't affect the visibility state (unless= you move the window off-screen perhaps) which is why your code ends up wai= ting forever.=C2=A0<div><br></div><div>If you want to wait for a window to = be visible, you should first check to see if it is already visible. Otherwi= se you'll end up waiting for it to become invisible.</div></div><br><di= v class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Fri, Feb 1= 4, 2020 at 7:48 AM Vasilis Vlachoudis <<a href=3D"mailto:Vasilis.Vlachou= [email protected]">[email protected]</a>> wrote:<br></div><blockquote= class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px so= lid rgb(204,204,204);padding-left:1ex">In some dialogs I wanted to restore = the size from the last time it was opened<br> therefore, before calling the wait_window I have<br> <br> self.wait_visibility()<br> self.geometry(...restore...)=C2=A0 =C2=A0 =C2=A0#<<< the geometry = setting will not work if it is not visible<br> self.wait_window()<br> <br> If something happens during the filling of the dialog information I show a = messagebox.<br> The messagebox is triggering the event loop, which displays also the dialog= <br> If the dialog is displayed then the execution gets stuck in the=C2=A0 "= ;wait_visibility", <br> and when the user closes the dialog, the execution proceeds to the wait_win= dow<br> which causes an exception since the window do not longer exits.<br> <br> I think it is a tk bug, that the wait_visibility waits despite the window i= s visible.<br> The only way to cure it is to add a check "if self.winfo_ismapped()&qu= ot;<br> <br> Example:<br> <br> <br> import tkinter as tk<br> import tkinter.messagebox as messagebox<br> <br> error =3D True<br> <br> class Dialog(tk.Toplevel):<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 width=C2=A0 =3D 320<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 height =3D 240<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 def __init__(self, master, *args):<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 super().__init__(ma= ster, *args)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.transient(mast= er)<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.b =3D tk.Butto= n(self, text=3D"Close", command=3Dself.close)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.b.pack()<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if error:<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 messagebox.showerror("Error",<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Something happened",<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 parent=3Dself)<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #if not self.winfo_= ismapped(): self.wait_visibility()<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.wait_visibilit= y()<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if Dialog.width>= 0:<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 self.geometry(f"{Dialog.width}x{Dialog.height}")<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.wait_window()<= br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 def close(self):<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # save size... and = destroy...<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.destroy()<br> <br> <br> root =3D tk.Tk()<br> dlg =3D Dialog(root)<br> _______________________________________________<br> Tkinter-discuss mailing list<br> <a href=3D"mailto:[email protected]" target=3D"_blank">Tkinter-dis= [email protected]</a><br> <a href=3D"https://mail.python.org/mailman/listinfo/tkinter-discuss" rel=3D= "noreferrer" target=3D"_blank">https://mail.python.org/mailman/listinfo/tki= nter-discuss</a><br> </blockquote></div> --000000000000038387059e8a4b7b-- --===============0457166853886333434== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Tkinter-discuss mailing list [email protected] https://mail.python.org/mailman/listinfo/tkinter-discuss --===============0457166853886333434==--