Mike Vlad
Mike Vlad

Reputation: 371

Control window and Display window

I need two PyQt windows to run in the same time on a multiple display machine: one screen for display and the other for input. In the following example i'm trying to have a simple window with a button and another window with a label. When i push the button, the other windows label text should change:

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_())

With InputWindows.update() i'm getting that first argument of unbound method must have a type QWidget and if i try InputWindows.label.update() i'm getting type object inputwindows has no attribute label

Upvotes: 1

Views: 479

Answers (1)

eyllanesc
eyllanesc

Reputation: 244003

InputWindows is a class, it is an abstraction so you generally have to create an object, I ask you: if you have n Windows InputWindows, to which window would you update the text ?, we would not know, so by simple logic we see that it is wrong to do it. On the other hand, consider each class as a black box where it is stimulated by inputs, and outputs are obtained, in your case Control_Pannel must have an output: the new text, but that output is asynchronous since it changes and must be used when changing , and that in Qt is a signal, so we must create it. On the other hand, InputWindows must receive the information to create a slot that updates the text in the QLabel as shown below:

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_())

Upvotes: 2

Related Questions