窗口在Python 3中冻结

时间:2017-05-10 16:54:28

标签: python user-interface tkinter

我在mac上使用python3并使用IDLE运行脚本,该脚本随python3安装自动生成。

我正在尝试向用户发出警报并找到该命令 tkinter.messagebox.showinfo("title","some text")

所以我尝试了一个最小的脚本来检查我是否可以使用该命令

import tkinter 

tkinter.messagebox.showinfo("test" , "blabla")

窗口显示正确但是当我点击" OK"时,它没有响应。按钮。 另外,当我启动脚本时会出现第二个空窗口。

对此有何解释或至少如何解决?

1 个答案:

答案 0 :(得分:2)

tkinter并非旨在以这种方式工作。每个tkinter都需要一个根窗口。如果你没有明确地创建一个(并且你没有),那么将为你创建一个。这就是空白窗口。

此外,除非有正在运行的事件循环,否则tkinter GUI无法正常运行。这是必要的,因为某些功能(例如响应按钮和重绘窗口)仅在响应事件时发生。如果事件循环未运行,则无法处理事件。

底线:对话框并非设计为在正确的tkinter应用程序的上下文之外使用。

独立使用的包装

以下代码可用于在独立模式下显示其中一个对话框。它的工作原理是创建和隐藏根窗口,显示对话框,然后销毁根窗口。

import tkinter as tk
from tkinter import messagebox

def show_dialog(func, *args, **kwargs):
    # create root window, then hide it
    root = tk.Tk()
    root.withdraw()

    # create a mutable variable for storing the result
    result = []

    # local function to call the dialog after the
    # event loop starts
    def show_dialog():

        # show the dialog; this will block until the
        # dialog is dismissed by the user
        result.append(func(*args, **kwargs))

        # destroy the root window when the dialog is dismissed
        # note: this will cause the event loop (mainloop) to end
        root.destroy()

    # run the function after the event loop is initialized
    root.after_idle(show_dialog)

    # start the event loop, then kill the tcl interpreter
    # once the root window has been destroyed
    root.mainloop()
    root.quit()

    # pop the result and return
    return result.pop()

要使用它,请将所需的对话框作为第一个选项,然后是特定于对话框的选项。

例如:

result = show_dialog(messagebox.askokcancel, "title", "Are you sure?")
if result:
    print("you answered OK")
else:
    print("you cancelled")