我知道Tkinter有时会很沮丧,但我对Tkinter / ttk Toplevel小部件/窗口的“正确”调用顺序感到难过:
在center of the screen中显示窗口,不要将其偏离中心,然后移动它。
正确调整窗口大小。
使窗口顶层到父窗体,但不是系统模式(即,不要偏向系统上的所有应用程序/窗口)。
可选择在Windows上创建任务栏按钮。
这是我目前的代码,为简单起见删除了一些不相关的位:
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__
此表单继承自我创建的自定义类,它包装了一组创建小部件的调用,并且该类继承自object
。第二个继承来自ttk.Toplevel
,允许它访问各种self.wm_*
调用和其他Tkinter好东西。
那就是说,我确定我的一些函数调用是不需要的。但是这个特定的调用顺序似乎在Windows 7上运行良好。在X11-over-ssh下(对于Windows中的X服务器使用Xming),事情变得有点怪异。在这种情况下,如果我将self.update()
移动到self.withdraw()
之后,则窗口正确居中,无需在Windows 7上重绘,但在X11上,它被绘制并在隐藏时正确居中,但是ZERO几何(仅显示压缩的窗口边框/装饰)。这是因为网格传播没有激发等等。
但是self.update()
现在在哪里,它在窗口和X11上都适当地调整窗口的大小和居中 - 但你可以看到窗口偏离中心创建,然后移动到两者的中心。
如果我在Windows上使用self.wm_attributes("-toolwindow", 1)
,那么窗口会在没有我看到的情况下居中,但-toolwindow
仅适用于Windows系统。这对X11和Aqua都是无效的命令。
我想避免一直调用tk::windowingsystem
来确定我的窗口管理器是什么,并且必须为Windows和X11应用不同的黑客。我无法测试Mac / Aqua(不拥有一个,不会购买),所以我只能希望最终的外观在该平台上有所作用。
此外,如果我点击Windows和远程X11下的另一个窗口/应用程序,通过任务栏按钮单击主窗体只会显示主窗体 - 只有当Toplevel窗口子窗口弹出时才会弹出你点击主窗体内的任何地方。 修正 :(有点) - 我忘了向self._transient()
添加一个参数,通过指定父级来修复它。今晚早些时候,我没有通过父母的论证,因此焦点不对。
对Ancient Mu的牧师有一些经过验证的魔法配方或调用,以获得Tkinter / ttk Toplevel窗口的大小,居中和正确获取焦点,如果它不是根窗口?使用最小的X11,Motif-look,btw。
不,我没有使用PyGTK,PyQT,wxPython或其他一些工具包。它是标准的Tkinter / ttk或bust,因为这是我在过去几周学习和编写包装函数的过程。我工作的自动完成组合框是一个可爱的小装置。仍然有点小马车,但这是另一个SO问题的话题......
PS ,Effbot上的Tkinter食谱已经关闭。看起来像服务器崩溃。有没有人碰巧偶然镜像那个网站?
答案 0 :(得分:2)
解决!不得不稍微调整一下调用的顺序:
#// Done!
self.withdraw()
self.grid()
self.transient(self._parent)
self.grab_set()
self.form.initial_focus()
center(self)
self.deiconify()
self._parent._parent.wait_window(self)
但真正的解决方法是在center()
我从[{3}}取消的winfo_width()
函数,将调用更改为winfo_height()
/ winfo_reqwidth()
到winfo_reqheight()
/ {{ 1}}并添加对update()
的调用作为center()
中的第一个调用。现在,我将对话框窗口弹出中心而不会看到它们移动,焦点正确应用,并且它可以在Windows和远程X11上运行。也许有一天,我会发现它在Mac OS X / Aqua上的效果如何。