gpt4 book ai didi

Python3,理解 tkinter-mainloop() 或 QtPy-exec_() 中的 "GUI loop"

转载 作者:太空宇宙 更新时间:2023-11-03 16:42:43 25 4
gpt4 key购买 nike

3个子问题:
[1] python GUI 是基于轮询的吗?
在我看来,tk 和 qtpy 都是基于轮询的,如果 gui 调用一个需要一段时间才能执行的函数,整个 gui 就会挂起。
我很久以前就了解了 gui,我记得现代 gui 应该是基于中断的,即使当 gui 正在执行一些大的事情时,gui 也应该始终响应。 gui 可能不会显示那些大计算的结果,但它会响应调整大小、显示按钮单击动画等。所以我的问题是,是否有一个选项,例如:

    #psuedo code
root=tkinter.Tk()
root.setInterruptMode(True)

[2] tk.mainloop() 只是一个巨大的循环吗?
如果我的第一个问题是一个白日梦,而我只需要学习线程和多进程,那么我的下一个问题是关于 root.mainloop() (或 qtpy 的 exec_() )。
我的印象是 mainloop() 并没有真正启动一个线程或 python 中的任何东西,它只是将一个巨大且不可见的 tkinter 的 gui 轮询+绘画循环打包到我的主线中。我的印象正确吗?

[3] 为什么要把 mainloop 放在主线中?
mainloop()必须驻留在主线吗?我可以线程/多处理它吗?这样我的主线就可以专注于大计算,主线控制gui进程和IO进程。我遇到的所有例子都有 mainloop()在主线中,我不确定这是推荐的方法或有什么好处。

下面是我在尝试学习 python gui 时编写的代码:

    import tkinter
import random

class myGUI():
def __init__(self, arg_tkroot):
self.GUI_display = tkinter.Label(arg_tkroot, text='init-ed')
self.GUI_button = tkinter.Button(arg_tkroot, text='click')
self.GUI_display.pack()
self.GUI_button.pack()

self.GUI_button.bind('<Button-1>', self.handle_user_interaction)
self.list_bigData = []

#handles GUI interaction, and call bigData_and_bigCalculation()
def handle_user_interaction(self, arg_event):
print(arg_event, ' detected by myGUI')
strResult_toFeedbackToUser = self.bigData_and_bigCalculation()
self.GUI_display.config(text=strResult_toFeedbackToUser)
print('finished handling user interact')

# slow calculations and memory consuming operations
def bigData_and_bigCalculation(self):
self.list_bigData[:]=[]
for i in range(500000):
self.list_bigData.append( ''.join(random.choice('asdfas') for k in range(10)) )
return self.list_bigData[-1]
# Main()
if __name__ == '__main__':
root = tkinter.Tk()
mygui = myGUI(root)
root.mainloop()

最佳答案

[1] GUIs are polling based?

GUI 是基于事件的——GUI 中发生的一切都是对事件的响应。应用程序如何处理事件取决于应用程序。如果事件的处理可以在几百毫秒或更短的时间内发生,则可以在主线程中进行处理。如果需要更长的时间,应用程序应该在单独的线程或进程中运行代码。

就 Tkinter 而言,Tkinter 被设计为在单线程中运行。这并不意味着您不能使用线程,只是对 tkinter 对象的所有访问都应该在单个线程上。常见的方法是让其他线程通过线程安全队列与 GUI 进行通信,GUI 线程负责定期检查该队列。

So my question is, Is there an option like [root.setInterruptMode(True)]

在 tkinter 中,不,没有办法进入特殊的“中断”模式。

[2] It is just a gigantic loop?

我假设“它”是指对mainloop的调用。是的,这是一个巨大的循环。或者更正确地说,这是一个小循环。它所做的只是等待事件,然后查找该事件的处理程序并运行该处理程序。

My impression is that mainloop() doesn't really start a thread or anything in python

正确。它在当前线程中运行事件循环。

[3] why putting mainloop in Main line?

您必须询问原始开发人员。可能是因为这对于非常非常大比例的应用程序来说是必需的(也许在发明工具包时比现在更真实)。

Tkinter 只是 tcl 解释器的包装器,并在解释器中加载了 tk 工具包。 tcl/tk 被设计为嵌入到其他应用程序中,因此它需要轻量级,并且能够在不支持线程的系统上运行(tcl 已经足够老了,无法保证每个平台上都支持线程)

Does mainloop() have to reside in the Main line? can I thread/multiprocess it out?

mainloop() 需要在创建根窗口的同一线程中运行。如果您需要线程(同样,您很可能不需要),您当然可以在单独的线程中运行事件处理程序。它增加了复杂性,但如果您需要它,它就在那里。对于一大类程序,根本不需要那么复杂。

您应该能够创建一个工作线程并从那里创建并运行您的 GUI。我从未尝试过,但我认为没有理由它不起作用。 Tkinter 并不关心它是主线程,只关心所有 tkinter 代码都在同一个线程中运行。

All the examples I came across have mainloop() in the Main line, I am not sure it is a recommended approach or what the benefits are.

在主线程中调用 mainloop 是 tkinter 的设计工作方式。如果您有长时间运行的计算,则应该将这些计算放在单独的线程或进程中。

关于Python3,理解 tkinter-mainloop() 或 QtPy-exec_() 中的 "GUI loop",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36654074/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com