- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
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/
我正在使用 PySide 和 PyQt 进行 GUI 开发。我一直在使用这些代码来运行 GUI 应用程序: app = QApplication(sys.argv) ex = MyWin() ex.s
PyQt 新手。有人可以向我解释为什么我们这样做: sys.exit(app.exec_()) 代替: app.exec_() sys.exit() 我已经尝试过并且都有效。问题 2:我认为 sys
我正在尝试为我的项目编写系统测试。我有一个启动各种窗口的 Controller 类。但是,我似乎无法使用 exec 和 qtbot 来控制 Windows 启动。 这是一个 MVCE: from Py
在我基于 Qt 的应用程序(使用 PyQt 4.8.6 构建)中,我有一个类,它是 QtGui.QDialog 的子类: class ModelDialog(QtGui.QDialog): .
这段向前移植 exec 的代码是如何工作的? # Implementation of exec_ is from ``six``: if PY3: import builtins ex
我正在使用自定义 QFileDialog 因为我想选择多个目录。但是 exec_ 函数很慢,我不明白为什么。我使用的是最新版本的 PyQt。 代码片段: from PyQt4 import QtGui
我的代码如下所示: app = QApplication(sys.argv) self.interface = Interface() # The figure self.fig = self.int
以下代码有效(而且非常简单): class Scrape(QApplication): def __init__(self): super(Scrape, self).__init__(Non
我正在 PyQt 中开发一个软件来编辑游戏中的图 block map - 它支持许多我的游戏独有的功能。 我的游戏主要有小 map ,但我想尝试制作更大的 map - 但不幸的是,我的编辑器似乎对更大
我是 PyQt 的新手,所以当我创建 UI 文件时,我只是复制了一个主窗口 (mainfile.ui) 并将其更改为生成另一个 UI 文件 (Intro.ui)。我知道这不是创建 UI 文件的好方法,
我是 PyQt 的新手,所以当我创建 UI 文件时,我只是复制了一个主窗口 (mainfile.ui) 并将其更改为生成另一个 UI 文件 (Intro.ui)。我知道这不是创建 UI 文件的好方法,
app = QtGui.QApplication(sys.argv) # some code app.exec_() sys.exit() 或 sys.exit(app.exec_()) # This
我有这段代码,效果很好: import sys from PyQt4 import QtGui def main_window(): app = QtGui.QApplication(sys.
我使用 Python 3 和 PyQt5。这是我的测试 PyQt5 程序,关注最后两行: from PyQt5.QtCore import * from PyQt5.QtWidgets import
我使用的是 Python 2.7 和 PyQT4。 我想隐藏一个模态 QDialog 实例,然后再次显示它。但是,当调用dialog.setVisible(false)时(例如,使用QTimer),d
3个子问题: [1] python GUI 是基于轮询的吗? 在我看来,tk 和 qtpy 都是基于轮询的,如果 gui 调用一个需要一段时间才能执行的函数,整个 gui 就会挂起。 我很久以前就了解
谁能解释一下使用 sys.exit(app.exec_()) 而不是更简单的 app.exec_() 在 PyQt 中启动 GUI 的相对优点? 我是 PyQt 的新手并且已经看过这两个示例。 最佳答
我是一名优秀的程序员,十分优秀!