Tkinter-在禁用的文本框上拖动鼠标会停止update()

时间:2018-08-01 16:22:40

标签: python python-3.x tkinter

我正在编写一个程序,该程序使用了某种从用户角度来看的小部件,列出了“不可编辑”和“不可选择”的数据行。

该小部件还应该具有一个滚动条,因此我的小部件选项受我的了解有所限制。

此外,该应用程序显示不断更新的数字。

我去了一个文本框-但是,当我按住鼠标左键并在文本框root上移动鼠标时,update()会停止/等待。

我在下面编写了一些示例代码来演示这种现象。

import time
from tkinter import *

class App:
    def __init__(self):
        self.root = Tk()
        self.root.geometry("500x500")
        self.root.resizable(False, False)

        self.main_frame = Frame(self.root)
        self.main_frame.grid(row = 0, column = 0, sticky = "news")

        self.main_text_box = Text(self.main_frame)
        self.main_text_box.grid(row = 0, column = 0, sticky = "news")
        self.main_text_box.tag_configure("bold", font = "Helvetica 50")
        self.main_text_box.insert(END, "Example text", "bold")
        self.main_text_box.configure(state = DISABLED)

    def update(self):
        self.root.update()


def main():
    application = App()
    time_start = time.time()
    while True:
        application.update()
        print("Program running, {} seconds since start".format(
            round(time.time() - time_start, 3)))

if __name__ == "__main__":
    main()

当用户在文本框上拖动鼠标时,打印语句为

while True:

等待root.update()。

基本上,我的问题是:如果将鼠标拖动到禁用的文本框上,有什么方法可以让root.update()等待?

(注意-我是这个网站的新手,所以如果我不清楚或有什么问题,请指出我可以做的更好的事情:))

谢谢!

edit:对不起,我忘了提到我使用的是update(),因为在我的实际程序中(我没有在b / c中发布它的800多个行),我还有其他的非tkinter update()方法在while循环中,以便我可以每帧更新其他数据。

2 个答案:

答案 0 :(得分:3)

您不需要使用update()管理tkinter实例的循环,mainloop()将为您完成此操作。

相反,让我们在类从Tk()继承的地方编写此代码,然后将时间打印功能作为类的一部分。我们也可以使用after()来更新打印。最后,我们应该将time_start设置为要在我们的时间函数中使用的类属性。

import time
import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.geometry("500x500")
        self.resizable(False, False)

        self.time_start = time.time()

        self.main_frame = tk.Frame(self)
        self.main_frame.grid(row = 0, column = 0, sticky = "news")

        self.main_text_box = tk.Text(self.main_frame)
        self.main_text_box.grid(row = 0, column = 0, sticky = "news")
        self.main_text_box.tag_configure("bold", font = "Helvetica 50")
        self.main_text_box.insert("end", "Example text", "bold")
        self.main_text_box.configure(state = "disabled")
        self.time_check()

    def time_check(self):
        print("Program running, {} seconds since start".format(round(time.time() - self.time_start, 3)))
        self.after(100, self.time_check)

if __name__ == "__main__":
    my_app = App()
    my_app.mainloop()

答案 1 :(得分:2)

我无法完全重现所描述的问题;但是,某些反模式需要在发布的代码中进行纠正:

  • 使用mainloop代替while循环。
  • 避免调用update,mainloop会为您处理。
  • 使用root.after重复调用一个方法。

我更改了您的App类,使其继承自tk.Tk;您可以改为从Frame继承;在这种情况下,您必须为其提供主人。
我还把控制台打印放在班外的一个函数中,因为感觉更适合将控制台输出分开。

import time
import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.geometry("500x500")
        self.resizable(False, False)

        self.main_frame = Frame(self)
        self.main_frame.grid(row = 0, column = 0, sticky = "news")

        self.main_text_box = Text(self.main_frame)
        self.main_text_box.grid(row = 0, column = 0, sticky = "news")
        self.main_text_box.tag_configure("bold", font = "Helvetica 50")
        self.main_text_box.insert(END, "Example text", "bold")
        self.main_text_box.configure(state = DISABLED)

        self._update_me()

    def _update_me(self):
        print_time()
        self.after(500, self._update_me)

def print_time():
    print("Program running, {} seconds since start".format(
            round(time.time() - time_start, 3)))

def main():
    application = App()
    application.mainloop()


if __name__ == "__main__":
    time_start = time.time()
    main()