Home > other >  Call a function on another Pyside/Pyqt screen
Call a function on another Pyside/Pyqt screen

Time:06-06

I currently have an application in Pyside2 The file structure looks like this:

Files:

screen1.py

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(368, 275)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.pushButton = QPushButton(self.centralwidget)
        self.pushButton.setObjectName(u"pushButton")
        self.verticalLayout.addWidget(self.pushButton)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setObjectName(u"menubar")
        self.menubar.setGeometry(QRect(0, 0, 368, 21))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName(u"statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)
    # setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
        self.pushButton.setText(QCoreApplication.translate("MainWindow", u"Go to screen 2 and create widget", None))
    # retranslateUi

screen2.py :

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *

class Ui_Form(object):
    def setupUi(self, Form):
        if not Form.objectName():
            Form.setObjectName(u"Form")
        Form.resize(348, 227)
        self.add_widget = QPushButton(Form)
        self.add_widget.setObjectName(u"add_widget")
        self.add_widget.setGeometry(QRect(9, 120, 174, 23))

        self.retranslateUi(Form)

        QMetaObject.connectSlotsByName(Form)
    # setupUi

    def retranslateUi(self, Form):
        Form.setWindowTitle(QCoreApplication.translate("Form", u"Form", None))
        self.add_widget.setText(QCoreApplication.translate("Form", u"create stackerdwidget on screen 1", None))
    # retranslateUi

main.py :

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2 import QtWidgets
from screen1 import Ui_MainWindow
from screen2 import Ui_Form
import sys



class win2(QtWidgets.QMainWindow, Ui_Form):
    def __init__(self):
        super(win2, self).__init__()
        self.setupUi(self)
        self.add_widget.clicked.connect(lambda:win1.creat_stackedwidget(self))


class win1(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(win1, self).__init__()
        self.setupUi(self)
        self.show()
        self.pushButton.clicked.connect(self.open_win2)
    
    def open_win2(self):
        self.tela2 = win2()
        self.tela2.show()
        
    def creat_stackedwidget(self):
        print("here")
        self.stackedWidget = QStackedWidget(self.centralwidget)
        self.stackedWidget.setObjectName(u"stackedWidget")
        self.stackedWidget.setStyleSheet(u"background-color: rgb(0, 0, 0);")
        self.page = QWidget()
        self.page.setObjectName(u"page")
        self.stackedWidget.addWidget(self.page)
        self.page_2 = QWidget()
        self.page_2.setObjectName(u"page_2")
        self.stackedWidget.addWidget(self.page_2)
        self.verticalLayout.addWidget(self.stackedWidget)
        
        

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    mainWin = win1()
    ret = app.exec_()
    sys.exit()

The main question is how can I call a function creat_stackedwidget from screen 2 so that the stackedwidget is executed and created on screen1 , without giving the error :

“ AttributeError: 'win2' object has no attribute 'centralwidget''”

The function in this case will create a stackedWidget inside screen 1 when it is executed on screen 2 through a button when clicked. Note: if I define the creat_stackedwidget in the screen class 1 in main.py it creates the stackedwidget normally.

class win1(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(win1, self).__init__()
        self.setupUi(self)
        self.show()
        self.pushButton.clicked.connect(lambda:self.creat_stackedwidget())

CodePudding user response:

The reason you are getting the error is because win2 doesn't know what win1 is.

You can create a Signal on your second window that can be triggered by it's button and the signal window 1 can listen for the signal and create the stacked widget when it is pressed.

For example:

main.py

class win2(QtWidgets.QMainWindow, Ui_Form):
    stackSignal = Signal()  # added this

    def __init__(self):
        super(win2, self).__init__()
        self.setupUi(self)
        self.add_widget.clicked.connect(lambda: self.stackSignal.emit())  # changed this


class win1(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(win1, self).__init__()
        self.setupUi(self)
        self.show()
        self.pushButton.clicked.connect(self.open_win2)

    def open_win2(self):
        self.tela2 = win2()
        self.tela2.stackSignal.connect(self.creat_stackedwidget) # added this
        self.tela2.show()

    def creat_stackedwidget(self):
        print("here")
        self.stackedWidget = QStackedWidget(self.centralwidget)
        self.stackedWidget.setObjectName(u"stackedWidget")
        ...

  • Related