简体   繁体   中英

How to switch between two PyQt5 MainWindow widgets

I'm writing a program that has two different parts to it - let's call them sub1 and sub2. When I initially run my program, sub1 displays and I'm loading sub2 in the background but not displaying it. I have a menu action in sub1 that allows you to switch to sub2 and there is a menu action in sub2 that allows you to switch back to sub1. The problem I have is when trying to switch back from sub2 to sub1. Going from sub1 to sub2 works fine; sub1 gets hidden and sub2 is displayed. However, when trying to show sub1 again, sub2 doesn't get hidden. I'm new to PyQt as well as Python so I don't know all the intricacies yet. So, the method I'm using is just something I figured through trial and error and by no means needs to be this way. Simplified code below.

#mass module
class MASS(PyQt5.QtWidgets.QMainWindow, massUi.Ui_MainWindow):
    def __init__(self):
        super(MASS, self).__init__()
        self.actionSwitchToCompEval.triggered.connect(self.switchToCompEval)

    def switchToCompEval(self):
        massForm = main.massForm
        massForm.hide()
        compForm = main.compForm
        compForm.show()

    def showMass(self):
        main(1)

def main(initiate=None):
    if initiate == None:
        main.app = PyQt5.QtWidgets.QApplication(sys.argv)
        main.massForm = MASS()
        main.compForm = CompEval.CompEval()
        main.massForm.show()
        main.app.exec_()    
    elif initiate == 1:
        main.massForm = MASS()
        main.compForm = CompEval.CompEval()
        main.compForm.hide()
        main.massForm.show()
    elif initiate == 2:
        pass

if __name__ == '__main__':
    main()    


#comp module

class CompEval(PyQt5.QtWidgets.QMainWindow, compEvalUi.Ui_MainWindow):
    def __init__(self):
        super(CompEval, self).__init__()
        self.actionSwitchToMASS.triggered.connect(self.switchToMass)

    def switchToMass(self):
        mass.MASS().showMass()

def main():
    form = CompEval()
    form.show()

In the switchToCompEval function, it seems to work fine to reference the main.massForm and main.compForm variables but when I try to go from sub2(comp) back to sub1(mass) I get an error that the function does not contain that variable, which seems odd to me. I am aware that several aspects of how I have this setup at the moment is odd and far from ideal, so any suggestions would be appreciated. Thanks.

So after much experimentation I determined the best solution to this problem is to combine the modules into one. IF you have multiple MainWindow widgets and you need to be able to switch back and forth between them, keep your classes that access the widgets all in the same module.

So I have my two widget classes:

import PyQt5
import sys
#Below are the modules that are auto-generated when using Qt Designer to make an interface
import compWidget as compEvalUi
import massWidget as massUi 

class MASS(PyQt5.QtWidgets.QMainWindow, massUi.Ui_MainWindow
    def __init__(self):
        super(MASS, self).__init__()
        #setupUi function is in the auto-generated module and contains all the attributes of the interface
        self.setupUi(self)
        #menuSwitch is the name of the button/menu item that would need to be clicked
        #in order to switch windows. 
        #The example shown here is if the action was attached to a menu-dropdown item
        #which is why 'triggered' is used as opposed to 'clicked' if it were attached to a button
        self.menuSwitch.triggered.connect(self.switchToCompWidget)

    def switchToCompWidget(self):
        INITIALIZE.massForm.hide()
        INITIALIZE.compForm.show()

class CompEval(PyQt5.QtWidgets.QMainWindow, compEvalUi.Ui_MainWindow):
    def __init__(self):
        super(CompEval, self).__init__()
        self.setupUi(self)
        self.menuSwitch.triggered.connect(self.switchToMassWidget)

    def switchToMassWidget(self):
        INITIALIZE.compForm.hide()
        INITIALIZE.massForm.show()

class INITIALIZE:
    def __init__(self):
        app = PyQt5.QtWidgets.QApplication(sys.argv)
        INITIALIZE.massForm = MASS()
        INITIALIZE.massForm.show()
        INITIALIZE.compForm = CompEval()
        app.exec_()

def main():
    program = INITIALIZE()

if __name__ =='__main__':
    main()

您可以使用信号和插槽来分隔逻辑,而不是在类之间共享全局参数。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM