如何将消息从 QWidget 发送到 QStatusBar?

Posted

技术标签:

【中文标题】如何将消息从 QWidget 发送到 QStatusBar?【英文标题】:How to send message from a QWidget to QStatusBar? 【发布时间】:2019-10-12 22:28:28 【问题描述】:

有没有办法在 PySide2 中将消息从 QWidget 发送到 QStatusBar?一种在发生某事时发出消息的方法,另一个对象接收它并相应地更改消息。

我一直在尝试使用 QObject.emit() 和 QObject.connect() 传递字符串并在 QStatusBar 上显示但没有结果,它们都在不同的类中。

我只使用了 emit 和 connect 来进行简单的操作,比如与父窗口一起关闭子窗口,所以如果 emit 和 connect 不是处理此问题的正确方法,请建议另一种传递消息的方法。

import os
import shutil

from PySide2 import QtWidgets
from PySide2.QtCore import SIGNAL, SLOT

class ChildWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(ChildWidget, self).__init__(parent)
        self.initUI()

    def initUI(self):
        self.setLayout(QtWidgets.QGridLayout())
        label_A = QtWidgets.QLabel("Path A: ", self)
        self.text_A = QtWidgets.QLineEdit(self)
        label_B = QtWidgets.QLabel("Path B: ", self)
        self.text_B = QtWidgets.QLineEdit(self)
        button_A = QtWidgets.QPushButton("Copy", self)

        button_A.clicked.connect(self.copy_function)

        self.layout().addWidget(label_A, 0, 0)
        self.layout().addWidget(self.text_A, 0, 1)
        self.layout().addWidget(label_B, 1, 0)
        self.layout().addWidget(self.text_B, 1, 1)
        self.layout().addWidget(button_A, 1, 2)

        self.layout().setColumnStretch(1, 1)
        self.layout().setColumnMinimumWidth(2, 72)

    def copy_function(self):
        source = self.text_A.text()
        destination = self.text_B.text()
        self.message = ''; count = 0

        file_list = os.listdir(source)
        for item in file_list:
            count = count + 1
            source_path = source +'/'+ item
            destination_path = destination +'/'+ item
            if os.path.isfile(source_path):
                shutil.copyfile(source_path, destination_path)
            # message
            self.message = 'Transferred 0 out of 1 files...'.format(
                count, len(file_list)
            )

class ParentWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(ParentWidget, self).__init__(parent)
        self.initUI()

    def initUI(self):
        self.child = ChildWidget()
        self.setLayout(QtWidgets.QGridLayout())
        self.status_bar = QtWidgets.QStatusBar(self)
        self.status_bar.setSizeGripEnabled(False)
        self.h_line = QtWidgets.QFrame(self)
        self.h_line.setFrameShape(self.h_line.HLine)
        self.h_line.setFrameShadow(self.h_line.Sunken)

        # self.status_bar.showMessage(message)

        self.layout().addWidget(self.child, 0, 0)
        self.layout().addWidget(self.h_line, 1, 0)
        self.layout().addWidget(self.status_bar, 2, 0)
        self.layout().setContentsMargins(0, 0, 0, 0)

        self.setWindowTitle("Copy Window")
        self.resize(600, 60)
        self.show()

widget_window = ParentWidget()

【问题讨论】:

提供minimal reproducible example 【参考方案1】:

我在一份 PyQt 文档中找到了它。这行得通。

import os
import shutil

from PySide2 import QtWidgets
from PySide2.QtCore import Signal, Slot

class ChildWidget(QtWidgets.QWidget):
    status_update = Signal(str)
    def __init__(self, parent=None):
        super(ChildWidget, self).__init__(parent)
        self.initUI()

    def initUI(self):
        self.setLayout(QtWidgets.QGridLayout())
        label_A = QtWidgets.QLabel("Path A: ", self)
        self.text_A = QtWidgets.QLineEdit(self)
        label_B = QtWidgets.QLabel("Path B: ", self)
        self.text_B = QtWidgets.QLineEdit(self)
        button_A = QtWidgets.QPushButton("Copy", self)

        button_A.clicked.connect(self.copy_function)

        self.layout().addWidget(label_A, 0, 0)
        self.layout().addWidget(self.text_A, 0, 1)
        self.layout().addWidget(label_B, 1, 0)
        self.layout().addWidget(self.text_B, 1, 1)
        self.layout().addWidget(button_A, 1, 2)

        self.layout().setColumnStretch(1, 1)
        self.layout().setColumnMinimumWidth(2, 72)

    def copy_function(self):
        source = self.text_A.text()
        destination = self.text_B.text()
        count = 0

        file_list = os.listdir(source)
        for item in file_list:
            count = count + 1
            source_path = source +'/'+ item
            destination_path = destination +'/'+ item
            if os.path.isfile(source_path):
                shutil.copyfile(source_path, destination_path)
            message = 'Transferred 0 out of 1 files...'.format(
                count, len(file_list)
            )
            self.status_update.emit(message)

class ParentWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(ParentWidget, self).__init__(parent)
        self.initUI()

    def initUI(self):
        self.child = ChildWidget()
        self.setLayout(QtWidgets.QGridLayout())
        self.status_bar = QtWidgets.QStatusBar(self)
        self.status_bar.setSizeGripEnabled(False)
        self.h_line = QtWidgets.QFrame(self)
        self.h_line.setFrameShape(self.h_line.HLine)
        self.h_line.setFrameShadow(self.h_line.Sunken)

        self.child.status_update.connect(self.status_message)

        self.layout().addWidget(self.child, 0, 0)
        self.layout().addWidget(self.h_line, 1, 0)
        self.layout().addWidget(self.status_bar, 2, 0)
        self.layout().setContentsMargins(0, 0, 0, 0)

        self.setWindowTitle("Copy Window")
        self.resize(600, 60)
        self.show()

    @Slot()
    def status_message(self, message):
        self.status_bar.showMessage(message)

widget_window = ParentWidget()

【讨论】:

什么?你不能从 QWidget 发送信号?这是如何工作的

以上是关于如何将消息从 QWidget 发送到 QStatusBar?的主要内容,如果未能解决你的问题,请参考以下文章

如何将繁体中文消息从 Java 发送到 IBM MQ

如何使用 WIFI 将消息从 android 设备发送到 PC

如何将 JMS 消息从 WildFly 10 发送到远程 ActiveMQ

你如何将消息从 Flask 服务器(Python)发送到 HTML 客户端?

如何将receiptid映射到smack中发送的消息

当两者都在运行时,如何将消息从一个 shell 脚本发送到另一个 shell 脚本?