Dialog as transient above current toplevel
Dear all, in my program I want to provide a more understandable text in the simple dialogs for exiting the program if there is modified buffer and some other messages. Instead of creating one dialog for each I use the tkinter dialog Dialog.py like import Dialog ... ans = Dialog.Dialog(self.winfo_toplevel(), {"title":"Multiple Plot", "text":"Continue with the next\nOr do all plots", "bitmap": Dialog.DIALOG_ICON, "default": 0, "strings": ("Next","All","Cancel")}) if ans.num==1: doall = True elif ans.num==2: break However the displayed dialog is centred over the desktop and not above the running application, which is rather confusing. Is there a way to center it over my toplevel window? Thanks in advance Vasilis
Hi, On Wed, 24 Aug 2016 13:01:01 +0000 Vasilis Vlachoudis <Vasilis.Vlachoudis@cern.ch> wrote:
However the displayed dialog is centred over the desktop and not above the running application, which is rather confusing. Is there a way to center it over my toplevel window?
unfortunately this geometry is hard-coded into Tk, so the answer is "no". You might want to try the tkSimpleDialog.Dialog class instead, by default these dialogs are placed somewhere into the upper left corner of the parent, however you would have to set up a messagebox-like dialog yourself, there is no convenience function for message boxes included. If using pmw is an option for you, you might also try the Pmw.Dialog , iirc there's an option to center the dialog onto its parent. Regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Madness has no purpose. Or reason. But it may have a goal. -- Spock, "The Alternative Factor", stardate 3088.7
Thanks! I was looking the code dialog.tcl and normally it should work since there is a "transient" command. I don't understand why it doesn't work. I've noticed that some times the transient() doesn't work if it is not placed very close the creation of the Toplevel. Anyhow I decide to replicate the dialog with python and here is the result if it can be useful for anyone. The only thing I didn't manage to make it work properly is the option_add() Also I've noticed that the "grid_anchor()" which is supposed to be present from tk 8.5 it is not accepted as a python command, so I am calling it from tk. class Dialog(Toplevel): def __init__(self, master=None, cnf={}, **kw): Toplevel.__init__(self, master, class_="Dialog", **kw) self.transient(master) self.title(cnf["title"]) self.iconname("Dialog") self.protocol("WM_DELETE_WINDOW", self.close) self.num = cnf["default"] cnf = _cnfmerge((cnf, kw)) # Fill the top part with bitmap and message (use the option # database for -wraplength and -font so that they can be # overridden by the caller). #self.option_add("*Dialog.msg.wrapLength","3i","widgetDefault") #self.option_add("*Dialog.msg.font","TkCaptionFont","widgetDefault") fbot = Frame(self, relief=RAISED, bd=1) ftop = Frame(self, relief=RAISED, bd=1) fbot.pack(side=BOTTOM, fill=BOTH) ftop.pack(side=TOP, fill=BOTH, expand=YES) self.tk.call("grid", "anchor", fbot._w, CENTER) #self.grid_anchor(CENTER) l = Label(ftop, text=cnf["text"], wraplength="3i", font="TkCaptionFont", justify=LEFT) l.pack(side=RIGHT, fill=BOTH, expand=YES, padx="3m", pady="3m") if cnf["bitmap"]: l = Label(ftop, bitmap=cnf["bitmap"]) l.pack(side=LEFT, padx="3m", pady="3m") # Create a row of buttons at the bottom of the dialog for i,s in enumerate(cnf["strings"]): b = Button(fbot, text=s, command=lambda s=self,n=i:s.close(n)) b.bind("<Return>", lambda e : e.widget.invoke()) if i==cnf["default"]: b.config(default="active") b.focus_set() else: b.config(default="normal") b.grid(column=i, row=0, sticky=EW, padx=10, pady=4) self.bind("<Escape>", lambda e,s=self:s.close()) self.bind("<Right>", lambda e : e.widget.event_generate("<Tab>")) self.bind("<Left>", lambda e : e.widget.event_generate("<Shift-Tab>")) self.deiconify() self.wait_visibility() self.grab_set() self.focus_set() self.wait_window() #----------------------------------------------------------------------- def close(self, num=-1): self.num = num self.destroy() ________________________________________ From: Tkinter-discuss [tkinter-discuss-bounces+vasilis.vlachoudis=cern.ch@python.org] on behalf of Michael Lange [klappnase@web.de] Sent: Thursday, August 25, 2016 00:54 To: tkinter-discuss@python.org Subject: Re: [Tkinter-discuss] Dialog as transient above current toplevel Hi, On Wed, 24 Aug 2016 13:01:01 +0000 Vasilis Vlachoudis <Vasilis.Vlachoudis@cern.ch> wrote:
However the displayed dialog is centred over the desktop and not above the running application, which is rather confusing. Is there a way to center it over my toplevel window?
unfortunately this geometry is hard-coded into Tk, so the answer is "no". You might want to try the tkSimpleDialog.Dialog class instead, by default these dialogs are placed somewhere into the upper left corner of the parent, however you would have to set up a messagebox-like dialog yourself, there is no convenience function for message boxes included. If using pmw is an option for you, you might also try the Pmw.Dialog , iirc there's an option to center the dialog onto its parent. Regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Madness has no purpose. Or reason. But it may have a goal. -- Spock, "The Alternative Factor", stardate 3088.7 _______________________________________________ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss
Hi, On Thu, 25 Aug 2016 14:51:43 +0000 Vasilis Vlachoudis <Vasilis.Vlachoudis@cern.ch> wrote:
Thanks! I was looking the code dialog.tcl and normally it should work since there is a "transient" command. I don't understand why it doesn't work.
"Transient" means here, that the window is always above its parent in the WM's stacking order. You can see this when you open such a dialog box and move it over the parent (if it's not already there) and then click into the parent window: the transient dialog will nontheless stay on top. This however has nothing to do with the coordinates where the window is placed on the screen. The relevant part for the latter in dialog.tcl is this, most interesting the comments (here at line 148): # 6. Withdraw the window, then update all the geometry information # so we know how big it wants to be, then center the window in the # display (Motif style) and de-iconify it. ::tk::PlaceWindow $w tkwait visibility $w Best regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Many Myths are based on truth -- Spock, "The Way to Eden", stardate 5832.3
participants (2)
-
Michael Lange -
Vasilis Vlachoudis