I know Tkinter can be an exercise in frustration at times, but I am stumped on the "correct" sequence of calls to a Tkinter/ttk Toplevel widget/window that will:
Display the window in the center of the screen WITHOUT drawing it off-center and THEN moving it.
Size the window properly.
Make the window toplevel to the parent form, but not system modal (that is, not toplevel to ALL apps/windows on the system).
Optionally create a taskbar button on Windows.
This is the current code that I have so far, with some unrelated bits removed for simplicity's sake:
def __init_ui__(self):
#// Basic setup.
self.wm_overrideredirect(False)
self.wm_resizable(False, False)
self.configure(relief=FLAT, borderwidth=4)
#// <Some extraneous widget-creation here>
#// Done!
self.update()
self.withdraw()
self.update_idletasks()
self.grid()
self.transient(self._parent)
self.grab_set()
self.form.initial_focus() #// sets initial focus before the window is displayed
center(self) #// https://stackoverflow.com/a/10018670
self.deiconify()
self._parent._parent.wait_window(self) #// Reaches back to the root Tk() obj.
# ENDIF
# END __init_ui__
This form inherits from a custom class I created that wraps a bunch of widget-creation calls, and the class inherits down from object
. A second inheritance comes from ttk.Toplevel
, to give it access to the various self.wm_*
calls and other Tkinter goodies.
That said, I am certain some of my function calls are unneeded. But this particular call order seems to mostly work well on Windows 7. Under X11-over-ssh (using Xming for the X server in Windows), however, things get a bit weirder. In that case, if I move self.update()
to be after self.withdraw()
, then the window is centered correctly w/o redraw on Windows 7, but on X11, it is drawn and properly centered whilst hidden, but has ZERO geometry (only the compressed window border/decorations are shown). It's as-if grid propagation didn't fire or such.
But where self.update()
is right now, it properly sizes and centers the window on both windows and X11 - but you can see the window getting created off-center THEN moved to center on both.
If I use self.wm_attributes("-toolwindow", 1)
on Windows, then the windows gets centered without me seeing it, but -toolwindow
only works on Windows system. It's an invalid command to both X11 and Aqua.
I'd like to avoid calls to tk::windowingsystem
all the time to determine what my window manager is and having to apply different hacks for Windows and X11. And I can't test Mac/Aqua (don't own one, not going to buy), so I'll just have to hope the end look is somewhat functional on that platform.
Additionally, if I click away to another window/app under both Windows and remote X11, clicking back on the main form via the taskbar button only displays the main form -- the child Toplevel window only pops back up when you click anywhere inside the main form. Fixed: (kinda) -- I forgot that adding an argument to self._transient()
kinda fixed that by specifying the parent. Earlier tonight, I didn't pass the parent argument in, thus the focusing wasn't right.
So is there some kind of tried-and-true magik recipe or invocation to the Priests of Ancient Mu to get a Tkinter/ttk Toplevel window to size, center, and properly get focus if it's not the root window? Using minimal X11, Motif-look, btw.
And no, I am not using PyGTK, PyQT, wxPython, or some other toolkit. It's standard Tkinter/ttk or bust, since that's what I've spent the last few weeks learning and writing wrapper functions for. The autocomplete combobox I worked up is a cute little contraption. Still slightly buggy, but that's a topic for another SO question...
PS, The Tkinter cookbook on Effbot is down. Looks like a server crash. Did anyone happen to mirror that site by chance?