首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PySide2非阻塞QMessageBox不显示文本

PySide2非阻塞QMessageBox不显示文本
EN

Stack Overflow用户
提问于 2019-03-06 05:51:34
回答 2查看 2.5K关注 0票数 2

当我的应用程序做一些耗时的事情时,我想在应用程序繁忙时向用户显示一个消息框。我不想要任何按钮(如OKCancel),也不能在消息框上调用exec_(),因为那是阻塞的。

我查看了许多qt站点,我需要的代码似乎归结为:

代码语言:javascript
运行
复制
    message_box = QMessageBox()
    message_box.setText(str('Reading Device, Please Wait...'))
    message_box.show()
    # do work here
    message_box.close()

当我运行代码时,我得到了消息框,但没有文本。我做错了什么?

我在下面包含了一个工作示例:

代码语言:javascript
运行
复制
#!/usr/bin/env python3

import sys
import time
from PySide2.QtWidgets import (QLineEdit, QPushButton, QApplication,
    QVBoxLayout, QDialog, QMessageBox)

class Form(QDialog):

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.button = QPushButton("Click Me")
        layout = QVBoxLayout()
        layout.addWidget(self.button)
        self.setLayout(layout)
        # Add button signal to dowork slot
        self.button.clicked.connect(self.dowork)

    def dowork(self):
        message_box = QMessageBox()
        message_box.setText(str('Reading Device, Please Wait...'))
        message_box.show()
        delay = 2.5
        while delay:
           sys.stdout.write('Working...\n')
           time.sleep(0.5)  # do some time-consuming stuff...
           delay -= 0.5
        message_box.close()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    form = Form()
    print('starting app...')
    form.show()
    sys.exit(app.exec_())

如果你点击这个按钮,消息框就会弹出来,并在“工作”完成时显示出来。当“工作”完成时,消息框会再次消失--这是理所应当的。但消息框中不显示任何文本。

这里有一个类似的问题:qmessagebox-not-show-text-when-call-show,但它没有回答我的问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-06 06:17:29

您不能有一个消耗大量时间(超过30ms)的任务,因为它会阻止GUI eventloop阻止Qt正常执行其工作,而是使用信号旁边的线程从另一个线程更新GUI:

代码语言:javascript
运行
复制
import sys
import threading
import time
from PySide2 import QtCore, QtWidgets

class Form(QtWidgets.QDialog):
    started = QtCore.Signal()
    finished = QtCore.Signal()

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.button = QtWidgets.QPushButton("Click Me")
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.button)
        # Add button signal to dowork slot
        self.button.clicked.connect(self.on_clicled)

        self._message_box = QtWidgets.QMessageBox()
        self._message_box.setText(str('Reading Device, Please Wait...'))
        self._message_box.setStandardButtons(QtWidgets.QMessageBox.NoButton)
        self.started.connect(self._message_box.show)
        self.finished.connect(self._message_box.accept)

    @QtCore.Slot()
    def on_clicled(self):
        thread = threading.Thread(target=self.dowork, daemon=True)
        thread.start()

    def dowork(self):
        delay = 2.5
        self.started.emit()
        while delay:
           sys.stdout.write('Working...\n')
           time.sleep(0.5)  # do some time-consuming stuff...
           delay -= 0.5
        self.finished.emit()

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    form = Form()
    print('starting app...')
    form.show()
    sys.exit(app.exec_())
票数 1
EN

Stack Overflow用户

发布于 2019-03-06 10:20:15

几乎可以肯定的是,您应该使用QProgressDialog。将最小值和最大值设置为零,以获得“不确定”的外观。

https://doc.qt.io/qt-5/qprogressdialog.html

尽管在setText()之后强制重绘可能会起作用:

代码语言:javascript
运行
复制
self._message_box.repaint()
QtWidgets.QApplication.processEvents()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55012166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档