PySide QApplication exec 与 while 循环的运用

4
基本上,我有一个程序会在PySide qt框架中创建一个基本的"Hello World"程序。不同之处在于,在调用exec_()之前,在while循环中执行print("loop")。问题在于,该循环在用户完成程序之前不会结束,因此只有在循环结束后才会调用exec_()

我的问题是,如果像这样运行它,print("loop")会运行,但窗口不会响应,并且不会显示"Hello, loop!"。如果将qt_app.exec_()缩进到while running:下面,则窗口将响应,但print("loop")仅在关闭窗口后执行一次并且不再执行。

我需要能够让主窗口在多次向控制台打印"loop"时保持响应状态。

import sys

from PySide.QtCore import *
from PySide.QtGui import *
qt_app = QApplication(sys.argv)
label = QLabel('Hello, loop!')
label.show()

running = True #only set to False when user is done with app in the real code.

while running:

  #I am handling connections here that MUST be in continual while loop
  print("loop")

qt_app.exec_()
1个回答

2
如果您想要一个GUI应用程序,您必须让GUI事件循环接管主线程。
解决您的问题的方法是创建一个单独的线程来进行打印,同时让qt事件循环接管主线程。
您的线程将在后台运行,完成它的工作,并且(因为我将其设置为守护进程)当应用程序完成或“running”变量设置为“False”时,它将停止。
import sys
import time
import threading

from PySide.QtCore import *
from PySide.QtGui import *
qt_app = QApplication(sys.argv)
label = QLabel('Hello, loop!')
label.show()

running = True #only set to False when user is done with app in the real code.

def worker():
    global running
    while running:
        #I am handling connections here that MUST be in continual while loop
        print("loop")
        time.sleep(0.5)

thread = threading.Thread(target=worker)
thread.setDaemon(True)
thread.start()

qt_app.exec_()

但这只是一个不好的例子,因为在线程中使用全局可变变量时应该加锁等等等等... 但这些都在文档中有详细说明。


我曾考虑过使用线程作为最后的手段,因为我认为它只是一种补丁而不是解决方案,也就是说,如果没有其他“合适”的方法来处理它。不用担心,我没有像这样的全局变量,所有东西都在类中并被设置为此类,这只是为了更好地结构化。 - cellsheet
没有其他“适当”的方法,因为您必须将主Python线程的控制权交给Qt事件循环。 - Viktor Kerkez
有没有办法能够在事件循环中设置代码,或者它基本上就被困在原地了? - cellsheet
将其移入Qt事件循环基本上就是这样。 - cellsheet
所有信号都在Qt事件循环中捕获,因此您可以将函数注册到特定信号,然后发出信号,该信号将在事件循环中被捕获,然后您的代码将在主线程中执行。但这是一个非常、非常、非常广泛的主题,如果没有具体的示例来说明您想要实现什么,我无法帮助您 :) - Viktor Kerkez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接