显示模式窗口时隐藏Tkinter根窗口

迈克尔·麦森(Michael Madsen)

我有一个基于TKinter的应用程序,它试图管​​理游戏的设置。用户可能安装了该游戏的多个版本,在这种情况下,我需要询问用户他们要在启动时管理哪个安装。该部分本身就可以很好地工作。构建主窗口后,将弹出选择对话框,并以模态方式运行。

但是,由于游戏版本之间的差异,如果我可以针对这些情况略微调整界面,将很有用。但是,这意味着我无法真正构建主窗口,直到我知道我正在进行的安装为止,因此在用户做出选择之前它将是空白的。

我想在显示该对话框时隐藏根窗口,但是withdraw在根窗口上调用只会导致也不显示模式对话框-Python最终挂起而没有CPU使用率,而且我不知道如何解决该问题而不必诉诸非模态窗口(以及我想避免的控制流程明显不同)。

展示问题和常规代码结构的示例代码(Python 2.7):

from Tkinter import *
from ttk import *

class TkGui(object):
    def __init__(self):
        self.root = root = Tk()
        self.root.withdraw()
        selector = FolderSelection(self.root, ('foo', 'bar'))
        self.root.deiconify()
        print(selector.result)

class ChildWindow(object): #Base class
    def __init__(self, parent, title):
        top = self.top = Toplevel(parent)
        self.parent = parent
        top.title(title)
        f = Frame(top)
        self.create_controls(f)
        f.pack(fill=BOTH, expand=Y)

    def create_controls(self, container):
        pass

    def make_modal(self, on_cancel):
        self.top.transient(self.parent)
        self.top.wait_visibility() # Python will hang here...
        self.top.grab_set()
        self.top.focus_set()
        self.top.protocol("WM_DELETE_WINDOW", on_cancel)
        self.top.wait_window(self.top) # ...or here, if wait_visibility is removed

class FolderSelection(ChildWindow):
    def __init__(self, parent, folders):
        self.parent = parent
        self.listvar = Variable(parent)
        self.folderlist = None
        super(FolderSelection, self).__init__(parent, 'Select folder')
        self.result = ''
        self.listvar.set(folders)
        self.make_modal(self.cancel)

    def create_controls(self, container):
        f = Frame(container)
        Label(
            f, text='Please select the folder '
            'you would like to use.').grid(column=0, row=0)
        self.folderlist = Listbox(
            f, listvariable=self.listvar, activestyle='dotbox')
        self.folderlist.grid(column=0, row=1, sticky="nsew")
        Button(
            f, text='OK', command=self.ok
            ).grid(column=0, row=2, sticky="s")
        self.folderlist.bind("<Double-1>", lambda e: self.ok())
        f.pack(fill=BOTH, expand=Y)

    def ok(self):
        if len(self.folderlist.curselection()) != 0:
            self.result = self.folderlist.get(self.folderlist.curselection()[0])
            self.top.protocol('WM_DELETE_WINDOW', None)
            self.top.destroy()

    def cancel(self):
        self.top.destroy()

TkGui()
北猫

看来,在您的情况下,模态窗口没有差异。实际上,您只需要使用该wait_window()方法。根据文档

在许多情况下,以同步方式处理对话框更为实用。创建对话框,显示它,等待用户关闭对话框,然后继续执行您的应用程序。正是我们需要的wait_window方法;它会进入一个本地事件循环,直到给定的窗口被销毁(通过destroy方法或显式地通过窗口管理器)后才会返回。

考虑以下非模态窗口示例:

from Tkinter import *

root = Tk()

def go():
   wdw = Toplevel()
   wdw.geometry('+400+400')
   e = Entry(wdw)
   e.pack()
   e.focus_set()
   #wdw.transient(root)
   #wdw.grab_set()
   root.wait_window(wdw)
   print 'done!'

Button(root, text='Go', command=go).pack()
Button(root, text='Quit', command=root.destroy).pack()

root.mainloop()

当您单击Go按钮时,将出现非模态对话框,但是代码将停止执​​行,并且done!仅在关闭对话框窗口后才会显示字符串

如果这是您想要的行为,那么这是修改后的形式的示例(我__init__在TkGui和make_modalmethod中进行了修改,还添加了mainloop()):

from Tkinter import *
from ttk import *

class TkGui(object):
    def __init__(self):
        self.root = root = Tk()
        self.root.withdraw()
        selector = FolderSelection(self.root, ('foo', 'bar'))
        self.root.deiconify()
        print(selector.result)

class ChildWindow(object): #Base class
    def __init__(self, parent, title):
        top = self.top = Toplevel(parent)
        self.parent = parent
        top.title(title)
        f = Frame(top)
        self.create_controls(f)
        f.pack(fill=BOTH, expand=Y)

    def create_controls(self, container):
        pass

    def make_modal(self, on_cancel):
        #self.top.transient(self.parent)
        #self.top.wait_visibility() # Python will hang here...
        #self.top.grab_set()
        self.top.focus_set()
        self.top.protocol("WM_DELETE_WINDOW", on_cancel)
        self.top.wait_window(self.top) # ...or here, if wait_visibility is removed

class FolderSelection(ChildWindow):
    def __init__(self, parent, folders):
        self.parent = parent
        self.listvar = Variable(parent)
        self.folderlist = None
        super(FolderSelection, self).__init__(parent, 'Select folder')
        self.result = ''
        self.listvar.set(folders)
        self.make_modal(self.cancel)

    def create_controls(self, container):
        f = Frame(container)
        Label(
            f, text='Please select the folder '
            'you would like to use.').grid(column=0, row=0)
        self.folderlist = Listbox(
            f, listvariable=self.listvar, activestyle='dotbox')
        self.folderlist.grid(column=0, row=1, sticky="nsew")
        Button(
            f, text='OK', command=self.ok
            ).grid(column=0, row=2, sticky="s")
        self.folderlist.bind("<Double-1>", lambda e: self.ok())
        f.pack(fill=BOTH, expand=Y)

    def ok(self):
        if len(self.folderlist.curselection()) != 0:
            self.result = self.folderlist.get(self.folderlist.curselection()[0])
            self.top.protocol('WM_DELETE_WINDOW', None)
            self.top.destroy()

    def cancel(self):
        self.top.destroy()

TkGui()
mainloop()

代码停止在线selector = FolderSelection(self.root, ('foo', 'bar')),然后在关闭对话框后继续执行。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用tkinter窗口时隐藏python shell

来自分类Dev

使用tkinter窗口时隐藏python shell

来自分类Dev

如何使用jQuery显示隐藏和显示模式弹出窗口

来自分类Dev

使用withdraw() 后无法再次显示Tkinter 根窗口

来自分类Dev

Tkinter根窗口不出现

来自分类Dev

无法删除 tkinter 根窗口

来自分类Dev

点击按钮时打开窗口,隐藏父窗口,当新窗口关闭时再次显示父窗口

来自分类Dev

舞台处于全屏模式时,JavaFX弹出窗口隐藏

来自分类Dev

设置几何形状时无法隐藏Tkinter窗口

来自分类Dev

Tkinter。如何在顶级窗口等待变量时销毁根窗口

来自分类Dev

Tkinter。如何在顶级窗口等待变量时销毁根窗口

来自分类Dev

隐藏父窗口,但显示子窗口

来自分类Dev

在打开顶级窗口时隐藏根窗口,并在销毁顶级时使其重新出现

来自分类Dev

显示模式窗口时,<ion-item>中的href中断

来自分类Dev

当用户单击链接jqgrid时显示模式弹出窗口

来自分类Dev

显示 MessageBox 时出现 Python 新 TKinter 窗口

来自分类Dev

隐藏窗口时发生InvalidOperationException

来自分类Dev

在JAVAScript模式弹出窗口中隐藏值

来自分类Dev

tkinter-无法隐藏嵌套的顶层窗口

来自分类Dev

Tkinter输出显示在Tkinter窗口外部

来自分类Dev

如何显示登录窗口和隐藏主窗口

来自分类Dev

在输入中选择文本时触发了鼠标上移事件,导致模式窗口隐藏

来自分类Dev

舞台处于全屏模式时,JavaFX弹出窗口处于隐藏状态

来自分类Dev

单击时显示弹出窗口

来自分类Dev

Javascript在单击按钮时隐藏正文,并在单击窗口时显示

来自分类Dev

Python Sublime Text输出窗口显示/隐藏

来自分类Dev

在Linux中以编程方式隐藏/显示窗口

来自分类Dev

Google Maps信息窗口显示/隐藏操作

来自分类Dev

在Linux中以编程方式隐藏/显示窗口

Related 相关文章

  1. 1

    使用tkinter窗口时隐藏python shell

  2. 2

    使用tkinter窗口时隐藏python shell

  3. 3

    如何使用jQuery显示隐藏和显示模式弹出窗口

  4. 4

    使用withdraw() 后无法再次显示Tkinter 根窗口

  5. 5

    Tkinter根窗口不出现

  6. 6

    无法删除 tkinter 根窗口

  7. 7

    点击按钮时打开窗口,隐藏父窗口,当新窗口关闭时再次显示父窗口

  8. 8

    舞台处于全屏模式时,JavaFX弹出窗口隐藏

  9. 9

    设置几何形状时无法隐藏Tkinter窗口

  10. 10

    Tkinter。如何在顶级窗口等待变量时销毁根窗口

  11. 11

    Tkinter。如何在顶级窗口等待变量时销毁根窗口

  12. 12

    隐藏父窗口,但显示子窗口

  13. 13

    在打开顶级窗口时隐藏根窗口,并在销毁顶级时使其重新出现

  14. 14

    显示模式窗口时,<ion-item>中的href中断

  15. 15

    当用户单击链接jqgrid时显示模式弹出窗口

  16. 16

    显示 MessageBox 时出现 Python 新 TKinter 窗口

  17. 17

    隐藏窗口时发生InvalidOperationException

  18. 18

    在JAVAScript模式弹出窗口中隐藏值

  19. 19

    tkinter-无法隐藏嵌套的顶层窗口

  20. 20

    Tkinter输出显示在Tkinter窗口外部

  21. 21

    如何显示登录窗口和隐藏主窗口

  22. 22

    在输入中选择文本时触发了鼠标上移事件,导致模式窗口隐藏

  23. 23

    舞台处于全屏模式时,JavaFX弹出窗口处于隐藏状态

  24. 24

    单击时显示弹出窗口

  25. 25

    Javascript在单击按钮时隐藏正文,并在单击窗口时显示

  26. 26

    Python Sublime Text输出窗口显示/隐藏

  27. 27

    在Linux中以编程方式隐藏/显示窗口

  28. 28

    Google Maps信息窗口显示/隐藏操作

  29. 29

    在Linux中以编程方式隐藏/显示窗口

热门标签

归档