【问题标题】:tkinter tk/toplevel execution pauses a callback's execution?tkinter tk/toplevel 执行暂停回调的执行?
【发布时间】:2017-06-23 01:01:33
【问题描述】:

我有一个程序需要一个对话框来询问存储在global 变量中的输入字符串;目前,我使用Toplevel 窗口作为主Tk 窗口的子窗口来执行此操作。问题是 global 变量已更改(这有效,我在回调方法中检查过),但是一旦我在 Toplevel 窗口上调用 destroy,该值就不会保留。

from Tkinter import *

class GUI:
    def __init__(self):
        """initialization"""
        # widgets

        self.window = Tk()

        get_string = Button(
            self.window,
            command = self.on_get_string,
            text = "Open string"
            )

        # pack the widgets

        get_string.pack()
        return

    def main(self):
        """the main method"""
        self.window.mainloop()
        return

    def on_get_string(self, event = None):
        """open the string window"""
        prompt = PromptString() # a dialog which prompts for a string

        print str(prompt.string) # None
        prompt.main()
        print str(prompt.string)
        return

class PromptString:
    def __init__(self):
        """initialization"""
        self.string = None # the string

        # widgets

        self.window = Toplevel()

        self.input = Entry(self.window)
        self.input.bind("<Return>", self.on_set_string)

        set_button = Button(
            self.window,
            command = self.on_set_string,
            text = "Set"
            )

        # pack the widgets

        self.input.pack(side = LEFT)
        set_button.pack(side = RIGHT)
        return

    def main(self):
        """the main method"""
        self.window.mainloop() # execution pauses after this line finishes
        return

    def get_input(self):
        """get the input"""
        return self.input.get()

    def on_set_string(self, event = None):
        """set the string variable and close the window"""
        self.string = self.get_input()
        self.window.destroy()
        return

GUI().main()

我无法解决这个问题,这让我很痛苦,但任何帮助都将不胜感激,我提前感谢你。

编辑:

对于造成的混乱,我深表歉意,但这次我实际上重现了该错误,尽管它与其说是错误,不如说是问题。问题是程序的 执行 在第 39 行的 prompt.main() 调用中停止。我尝试单击并输入 2 个后续值,它们以相反的顺序打印 after Tk 实例关闭。这种暂停执行是 Tkinter 的产物吗?我该如何解决这个问题?

编辑 1:

有问题的变量不是全局变量,而是PromptString 类的属性。

【问题讨论】:

  • 您的代码刚刚运行并很快退出。你期望看到什么?到run_top 中的 after 触发时,200 毫秒已经过去,并且在程序退出之前可能还没有调用 var.set
  • 保罗鲁尼是对的。您可以通过更改run_tk() 函数中的语句tk.after(1000, run_top)tk.after(2000, tk.destroy) 来减慢速度来证明这一点。之后,您的代码将起作用。另请注意,global var 在模块级别没有任何作用,可以省略。
  • 如果您发布的代码不正确,可以更改它,但不留下任何内容也无济于事。您现在使我的回答毫无意义,并且没有留下任何示例来查看和帮助您调试。请参阅minimal reproducible example
  • 感谢您的建议。与此同时,我尽可能以简洁的脚本复制并发布了这个问题。它在 Python 2.7 中。复制花费的时间比预期的要长,但它已经完成了。
  • 我已经删除了我的答案,因为问题已经完全改变了。

标签: python user-interface tkinter toplevel


【解决方案1】:

解决方案是使用Tkwait_window(other_window) 方法。这允许Tkinter 的执行结构不会停止执行。固定代码如下:

from Tkinter import *

class GUI:
    def __init__(self):
        """initialization"""
        # widgets

        self.window = Tk()

        get_string = Button(
            self.window,
            command = self.on_get_string,
            text = "Open string"
            )

        # pack the widgets

        get_string.pack()
        return

    def main(self):
        """the main method"""
        self.window.mainloop()
        return

    def on_get_string(self, event = None):
        """open the string window"""
        prompt = PromptString() # a dialog which prompts for a string

        print str(prompt.string) # None
        prompt.wait(self.window) # wait for the prompt
        print str(prompt.string)
        return

class PromptString:
    def __init__(self):
        """initialization"""
        self.string = None # the string

        # widgets

        self.window = Toplevel()

        self.input = Entry(self.window)
        self.input.bind("<Return>", self.on_set_string)

        set_button = Button(
            self.window,
            command = self.on_set_string,
            text = "Set"
            )

        # pack the widgets

        self.input.pack(side = LEFT)
        set_button.pack(side = RIGHT)
        return

    def main(self):
        """the main method"""
        self.window.mainloop() # execution pauses after this line finishes
        return

    def get_input(self):
        """get the input"""
        return self.input.get()

    def on_set_string(self, event = None):
        """set the string variable and close the window"""
        self.string = self.get_input()
        self.window.destroy()
        return

    def wait(self, other_window):
        """run the window as an offshoot of another window"""
        other_window.wait_window(self.window)
        return

GUI().main()

【讨论】:

    猜你喜欢
    • 2016-09-08
    • 2022-11-17
    • 2010-11-15
    • 2015-03-05
    • 2016-09-21
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多