PySide QWidget即时更新

1 投票
1 回答
2006 浏览
提问于 2025-04-17 12:43

在我的应用程序中,我有一个调用外部模块的代码,这个模块会启动一些线程,做一些事情,然后返回一个值。我想在这个过程开始之前显示一个消息框(QMessageBox),而在完成后更新一个标签(QLabel),但是我遇到了困难。代码大概是这样的(从按钮的QObject.connect调用):

def _process(self):
  self._message_box.show()

  for i in range(3):
     rv = external_module_function_with_threads() // blocking function call
     label = getattr(self, "label%d" % (i + 1))
     label.setText(rv)

当我点击按钮并调用这个函数时,消息框只在循环完成后才显示。标签也是在循环完成后才更新。我尝试在循环中调用label.repaint(),但这似乎只是让消息框提前出现(但里面没有文字)。

我知道我没有违反“从主线程以外进行GUI操作”的规则(...对吧?),那么有没有办法强制更新呢?

1 个回答

1

要使用你的消息框,可以用 self._message_box.exec_() 这个代码。根据我对你问题的理解,我觉得这个方法可以满足你的需求。

from PySide.QtCore import *
from PySide.QtGui  import *

import sys
import time


class Main(QWidget):

    def __init__(self, parent=None):
        super(Main, self).__init__(parent)

        layout = QVBoxLayout(self)

        button = QPushButton("Press me")
        self.label = QLabel("Run #")

        map(layout.addWidget, [button, self.label])
        button.pressed.connect(self.buttonPressed)

        self.messageBox = QMessageBox()

    def buttonPressed(self):
        self.messageBox.exec_()
        Thread().run(self.label)


class Thread(QThread):

    def run(self, label):
        for x in range(5):
            self.updateLabel(label)
            app.processEvents()
            time.sleep(.5)

    def updateLabel(self, label):
        try:
            number = int(label.text().split(" ")[-1])
            number += 1
        except ValueError:
            number = 0
        label.setText("Run %i" % number)


app = QApplication([])
main = Main()
main.show()
sys.exit(app.exec_())

撰写回答