【问题标题】:Tkinter: make function run periodically with after()Tkinter:使用 after() 使函数定期运行
【发布时间】:2021-02-28 19:29:23
【问题描述】:

我试图让一个函数定期运行。目的是在 tkinter 帧上打印串行数据。

最初这工作,使用线程。

def readSerial():
    global val1
    ser_bytes = ser.readline()
    ser_bytes = ser_bytes.decode("utf-8")
    val1 = ser_bytes
    scrollbar.insert("end", val1)
    scrollbar.see("end") #autoscroll to the end of the scrollbar


t1 = continuous_threading.PeriodicThread(0.1, readSerial)

frame2 = tk.Frame(root, bg='#80c1ff') #remove color later
frame2.place(relx=0, rely=0.1, relheight=1, relwidth=1, anchor='nw')
scrollbar = scrolledtext.ScrolledText(frame2)
scrollbar.place(relx=0, rely=0, relheight=0.9, relwidth=1, anchor='nw')

t1.start()
root.mainloop()

但是,我在关闭应用程序时遇到了错误。 您可以在此处阅读有关此内容的更多信息: Closing my tkinter serial app, gives me an exception

所以用户 AST 建议,我应该使用 after() 函数。

所以我尝试了这个:

我保持函数readSerial() 完全相同。我删除了所有涉及线程的行 (t1)。

最后是这个:

root.after(100, readSerial)
root.mainloop()

但这并没有按预期工作。

在我的 tkinter 框架中,只打印序列的第一行,然后没有其他内容。

如何使用after() 进行这项工作?正确的方法是什么?

【问题讨论】:

  • 使用root.after()的代码在哪里,我想你也忘了在函数内部使用root.after(),否则函数只会被调用一次。把root.after()放在里面基本上会创建一个区间循环。
  • @CoolCloud 谢谢。我在这个问题的选定答案上使用了第一个例子。 stackoverflow.com/questions/44085554/… 。而且他没有在函数内部使用after()。
  • 注意在第一个例子中,函数只会运行一次然后停止。如果您希望它定期运行,那么也可以在里面使用root.after()。虽然不能保证周期的准确度,但可能会有轻微的延迟。
  • 你想用在函数中插入after()的方式来回答,这样我就可以看到它是怎么写的,你会得到积分吗?
  • 我对阅读连载不熟悉。

标签: python-3.x multithreading tkinter serial-port pyserial


【解决方案1】:

您必须在函数内部使用after() 以便定期调用它,例如:

def readSerial():
    global val1
    ser_bytes = ser.readline()
    ser_bytes = ser_bytes.decode("utf-8")
    val1 = ser_bytes
    scrollbar.insert("end", val1)
    scrollbar.see("end") #autoscroll to the end of the scrollbar
    root.after(100,readSerial) # 100 ms is 0.1 second, you can change that

.... # Same code but remove the t1

readSerial()
root.mainloop()

这将继续大约每 100 毫秒重复一次该函数,不能保证在 100 毫秒准确调用该函数,但不会在 100 毫秒之前调用该函数。

【讨论】:

  • 对不起,它不起作用。它显示两行串行数据,然后滞后,然后一次显示很多行。
  • @user1584421 这是您的问题的答案,Tkinter:使用 after() 定期运行函数。问题可能是,它发生得很快吗?尝试增加时间
  • 你是对的,我使用 500 而不是 100,它可以工作。但它太慢了。我使用的是 9600 波特率。你知道我的案子的正确时间值吗?
  • @user1584421 不知道,也许问一个新问题,似乎与这个问题无关。
  • 如何在最后而不是开始时使用after 安排调用,这样函数将在安排新调用之前完全执行。
猜你喜欢
  • 2023-03-06
  • 1970-01-01
  • 2021-02-16
  • 1970-01-01
  • 1970-01-01
  • 2014-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多