PyQt5控制​​窗口和显示窗口

时间:2018-10-19 11:47:15

标签: python pyqt pyqt5

我需要两个PyQt窗口在多台显示器上同时运行:一个屏幕用于显示,另一个屏幕用于输入。 在下面的示例中,我尝试使用一个带有按钮的简单窗口和另一个带有标签的窗口。当我按下按钮时,其他窗口标签文本应更改:

import sys
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QApplication, QWidget, QDialog, QInputDialog,QDesktopWidget,QVBoxLayout,QPushButton,QMainWindow,QAction,QFileDialog,QGroupBox,QGridLayout,QLabel


class Control_Pannel(QWidget):

    def __init__(self):
        super().__init__()
        self.title = 'Main Control Pannel'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 400
        self.text = "Display text"
        self.InitializeUI()


    def InitializeUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left,self.top,self.width,self.height)
        self.inputBox = QGroupBox("Display")
        layout = QGridLayout()
        layout.setColumnStretch(1, 4)
        layout.setColumnStretch(2, 4)
        button = QPushButton('Push here to change text')
        layout.addWidget(button,0,0)
        button.clicked.connect(self.on_click)
        self.inputBox.setLayout(layout)
        windowLayout = QVBoxLayout()
        windowLayout.addWidget(self.inputBox)
        self.setLayout(windowLayout)
        self.show()

        app = QApplication(sys.argv)
        ex=InputWindows()
        sys.exit(app.exec_())


    @pyqtSlot()
    def on_click(self):
        InputWindows.text = "Modified text after button push"
        print(InputWindows.text)
        InputWindows.update()
        ##???? here i don't know how to make the changes be reflected in the other window, even if when i print the .text attribute it seems to have changed.



class InputWindows(QDialog):

    def __init__(self):
        super().__init__()
        self.title = 'Display Pannel'
        self.left = 5
        self.top = 5
        self.width = 300
        self.height = 300
        self.text = "Original Text"
        self.InitializeUI()

    def InitializeUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left,self.top,self.width,self.height)


        self.createDisplayGridLayout()
        windowLayout = QVBoxLayout()
        windowLayout.addWidget(self.horizontalGroupBox)
        self.setLayout(windowLayout)
        self.show()

    def createDisplayGridLayout(self):

        self.horizontalGroupBox = QGroupBox("Grid")
        layout = QGridLayout()
        layout.setColumnStretch(1, 4)
        layout.setColumnStretch(2, 4)
        self.label = QLabel(self.text)
        layout.addWidget(self.label,0,0) 



if __name__=='__main__':
    app=QApplication(sys.argv)
    ex=Control_Pannel()
    sys.exit(app.exec_())

有了InputWindows.update(),我就会得到first argument of unbound method must have a type QWidget,如果尝试InputWindows.label.update(),我就会得到type object inputwindows has no attribute label

1 个答案:

答案 0 :(得分:1)

InputWindows是一个类,它是一个抽象,因此您通常必须创建一个对象,我问您:如果您有n个Windows InputWindows,您将文本更新到哪个窗口,我们不知道,因此简单从逻辑上看,这样做是错误的。另一方面,将每个类都视为一个黑盒,在该类中它会受到输入的刺激并获得输出,在这种情况下,Control_Pannel必须具有输出:新文本,但是该输出是异步的,因为它会更改,并且必须在在Qt中改变,这是一个信号,因此我们必须创建它。另一方面,InputWindows必须接收该信息才能创建一个插槽,以更新QLabel中的文本,如下所示:

import sys
from PyQt5 import QtCore, QtWidgets


class Control_Pannel(QtWidgets.QWidget):
    sendSignal = QtCore.pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.title = 'Main Control Pannel'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 400
        self.text = "Display text"
        self.InitializeUI()

    def InitializeUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left,self.top,self.width,self.height)
        self.inputBox = QtWidgets.QGroupBox("Display")
        layout = QtWidgets.QGridLayout()
        layout.setColumnStretch(1, 4)
        layout.setColumnStretch(2, 4)
        button = QtWidgets.QPushButton('Push here to change text')
        layout.addWidget(button,0,0)
        button.clicked.connect(self.on_click)
        self.inputBox.setLayout(layout)
        windowLayout = QtWidgets.QVBoxLayout(self)
        windowLayout.addWidget(self.inputBox)

    @QtCore.pyqtSlot()
    def on_click(self):
        text = "Modified text after button push"
        self.sendSignal.emit(text)


class InputWindows(QtWidgets.QDialog):
    def __init__(self):
        super().__init__()
        self.title = 'Display Pannel'
        self.left = 5
        self.top = 5
        self.width = 300
        self.height = 300
        self.InitializeUI()
        self.setText("Original Text")

    @QtCore.pyqtSlot(str)
    def setText(self, text):
        self.label.setText(text)

    def InitializeUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left,self.top,self.width,self.height)
        self.createDisplayGridLayout()
        windowLayout = QtWidgets.QVBoxLayout(self)
        windowLayout.addWidget(self.horizontalGroupBox)
        self.setLayout(windowLayout)

    def createDisplayGridLayout(self):
        self.horizontalGroupBox = QtWidgets.QGroupBox("Grid")
        layout = QtWidgets.QGridLayout()
        layout.setColumnStretch(1, 4)
        layout.setColumnStretch(2, 4)
        self.label = QtWidgets.QLabel()
        layout.addWidget(self.label, 0, 0) 
        self.horizontalGroupBox.setLayout(layout)



if __name__=='__main__':
    app = QtWidgets.QApplication(sys.argv)

    ex1 = Control_Pannel()
    ex1.show()
    ex2 = InputWindows()
    ex2.show()

    ex1.sendSignal.connect(ex2.setText)

    sys.exit(app.exec_())