PySide QWidget 立即更新

发布于 2025-01-04 00:10:45 字数 548 浏览 1 评论 0原文

在我的应用程序中,我调用了一个外部模块,该模块生成一些线程,执行一些操作,然后返回一个值。我试图让 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 操作”规则(...对吗?),那么有没有办法强制更新?

In my application, I have a call to an external module which spawns some threads, does some stuff, then returns a value. I'm trying to get a QMessageBox to show before and a QLabel to update after this is complete, but I'm stumped. The code goes something like this (called from QObject.connect on a button):

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)

When I click the button and the function is called, the message box only shows after the loop completes. The labels only update after the loop completes as well. I tried calling label.repaint() in the loop, but all that seems to do is make the message box show up earlier (but with no text in it).

I know I'm not violating the "GUI operations from outside the main thread" rule (...right?), so is there a way to force an update?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏日浅笑〃 2025-01-11 00:10:45

对于消息框,请使用 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_())

For your message box use self._message_box.exec_(). From my understanding of your question, I think this will do what you want.

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_())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文