将Tkinter Toplevel窗口置于窗口和远程X11的中心?

时间:2013-06-27 10:21:22

标签: python-2.7 tkinter

我知道Tkinter有时会很沮丧,但我对Tkinter / ttk Toplevel小部件/窗口的“正确”调用顺序感到难过:

  1. center of the screen中显示窗口,不要将其偏离中心,然后移动它。

  2. 正确调整窗口大小。

  3. 使窗口顶层到父窗体,但不是系统模式(即,不要偏向系统上的所有应用程序/窗口)。

  4. 可选择在Windows上创建任务栏按钮。

  5. 这是我目前的代码,为简单起见删除了一些不相关的位:

    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食谱已经关闭。看起来像服务器崩溃。有没有人碰巧偶然镜像那个网站?

1 个答案:

答案 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上的效果如何。