10

我目前正在编写一个 win32gui python27 应用程序(我正在运行 win7)。我想知道是否可以从我的 mainloop() 创建一个新窗口并保持对它的关注,可能是通过停止主循环并停用根窗口。在一种伪代码示例中:

root=Tk()
#put in some widgets, such as statusbars, tkfileDialog widgets etc...
O=Toplevel()
OptionMenu(O) #wait for user to make his choices; btw: OptionMenu is a class...
tkFileDialog.askdirectory(...) #THEN interpret this line

基本上,我想实现 tkfiledialog 和 tksimpledialog 中的大多数小部件所做的事情:
例如从主窗口窃取焦点(不仅仅是控制台焦点,wm 焦点)并恢复主循环,直到所有内容之后, OptionMenu 已解决。我希望我可以让你们清楚我的目标,我几周前才开始 Tkinter 编程,可能会混淆和误解它背后的一些概念......
就是这样,伙计们!

4

3 回答 3

18

您正在寻找的概念称为“抓取”。Tkinter 支持多种方法的抓取。例如,要在顶层设置本地抓取,您将执行my_window.grab_set(). 本地抓取是此窗口从您的应用程序中的所有其他窗口抓取焦点的地方,但仅适用于您的应用程序。

您还可以进行全局抓取,这有效地冻结了您的整个显示,除了您的特定窗口。这是非常危险的,因为如果您的代码中有错误,您可以轻松地将自己锁定在自己的计算机之外。

抓取不会停用 mainloop 功能。这必须为您的窗口运行以处理事件。它只是将所有事件重定向到有抓取的窗口。

有关更多信息,请在此处阅读有关 grab_set 和其他抓取命令:http: //effbot.org/tkinterbook/widget.htm#Tkinter.Widget.grab_set-method

于 2013-04-11T10:48:59.740 回答
1

grab.set()对我的需求非常激进,并阻止了正常的窗口操作。这个答案是让一个 Tkinter 窗口在其他 Tkinter 窗口之上弹出。

在我的应用程序中,我有一个大窗口toplevel,它调用一个小得多的窗口top2,最初出现在toplevel.

如果用户在toplevel窗口内单击,它将获得焦点并扼杀小得多的top2窗口,直到toplevel窗口被拖出它为止。

解决方案是单击按钮toplevel重新启动top2top2open 函数知道它已经在运行,因此只需将其提升到顶部并为其提供焦点:

def play_items(self):
    ''' Play 1 or more songs in listbox.selection(). Define buttons:
            Close, Pause, Prev, Next, Commercial and Intermission
    '''

    if self.top2_is_active is True:
        self.top2.focus_force()     # Get focus
        self.top2.lift()            # Raise in stacking order
        root.update()
        return                      # Don't want to start playing again
于 2020-08-04T01:24:44.597 回答
1

在 Mac OS El Capitan 上,以上建议都不适合我。但基于这些提示,这样做:

class Window(Tk.Toplevel):
    ...
    def setActive(self):
        self.lift()
        self.focus_force()
        self.grab_set()
        self.grab_release()
    ...
于 2017-07-13T18:33:37.797 回答