Search code examples
python-3.xpyqt5qwidgetqapplication

must construct QApp before QWidget Pyqt5


I started new PyQt5 programme but I encounter the error "Must construct QApplication before QWidget".

I understand the error, but not find where my code constructs my QWidget first.

Here's my code:

class Main(QWidget):
    """ Main window """
    def __init__(self, *args):
        QWidget.__init__(self, *args)
        self.business_list = ['Acheté à', 'Vendu à']

    # Pet form
    petFormGroupBox = QGroupBox("Description de l'animal")
    pet_layout = QFormLayout()
    pet_layout.addRow(QLabel("Nom scientifique:"), QLineEdit())
    pet_layout.addRow(QLabel("Sexe:"), QLineEdit())
    pet_layout.addRow(QLabel("Année de naissance:"), QDateEdit())
    pet_layout.addRow(QLabel("Cause décès:"), QLineEdit())
    petFormGroupBox.setLayout(pet_layout)

    # Business form
    petBusinessFormGroupBox = QGroupBox("Achats / Ventes")
    pet_business_layout = QFormLayout()
    pet_layout.addRow(QLabel("Nom complet + N° d'autorisation"), QLineEdit())
    petBusinessFormGroupBox.setLayout(pet_business_layout)

    business_btn_group = QRadioButton()

    for each in self.business_list:
        self.business_list.append(QRadioButton(each))

    self.business_list[0].setChecked(True)
    business_choices_layout = QHBoxLayout()
    counter = 1
    for each in self.business_list:
        business_choices_layout.addWidget(each)
        business_btn_group.addButton(each)
        business_btn_group.setId(each, counter)

    pet_business_layout.addWidget(business_choices_layout)

    hbox = QHBoxLayout()
    hbox.addWidget(pet_layout)
    hbox.addWidget(pet_business_layout)

    self.setLayout(hbox)

class Cites(QMainWindow):
    """ Cites app """
    def __init__(self):
        QMainWindow.__init__(self)
        self.setWindowTitle('CITES')
        self.setWindowState(Qt.WindowMaximized)

        exitAct = QAction(QIcon('exit24.png'), 'Exit', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.triggered.connect(qApp.quit)

        fileMenu = self.menuBar().addMenu('File')
        fileMenu.addAction(exitAct)

        toolbar = self.addToolBar('Main')
        toolbar.addAction(exitAct)

        main = Main()
        self.setCentralWidget(main)

        self.statusBar().showMessage('Bienvenue dans CITES')

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

If you have any idea, I am happy!

A happy new year and enjoy your code :).

thanks per advance


Solution

  • Your code wasn't indented correctly. All lines in the Main class after # Pet form should have been indented twice (i.e. 8 spaces) so that they are part of the __init__ constructor. That way it will be executed when you create an object of type Main(), which should be done after after you have created a QApplication object.

    Currently it is only indented once (i.e. 4 spaces) which means that it is part of the class definition. These lines are therefor executed during the class definition, before you create the QApplication object. Hence the error message.

    The fix is easy, just indent the code like this:

    class Main(QWidget):
        """ Main window """
        def __init__(self, *args):
            QWidget.__init__(self, *args)
            self.business_list = ['Acheté à', 'Vendu à']
    
            # Pet form
            petFormGroupBox = QGroupBox("Description de l'animal")
            pet_layout = QFormLayout()
            pet_layout.addRow(QLabel("Nom scientifique:"), QLineEdit())
            pet_layout.addRow(QLabel("Sexe:"), QLineEdit())
            pet_layout.addRow(QLabel("Année de naissance:"), QDateEdit())
            pet_layout.addRow(QLabel("Cause décès:"), QLineEdit())
            petFormGroupBox.setLayout(pet_layout)
    
            # Business form
            petBusinessFormGroupBox = QGroupBox("Achats / Ventes")
            pet_business_layout = QFormLayout()
            pet_layout.addRow(QLabel("Nom complet + N° d'autorisation"), QLineEdit())
            petBusinessFormGroupBox.setLayout(pet_business_layout)
    
            business_btn_group = QRadioButton()
    
            for each in self.business_list:
                self.business_list.append(QRadioButton(each)) # infinite recursion here!
    
            self.business_list[0].setChecked(True)
            business_choices_layout = QHBoxLayout()
            counter = 1
            for each in self.business_list:
                business_choices_layout.addWidget(each)
                business_btn_group.addButton(each)
                business_btn_group.setId(each, counter)
    
            pet_business_layout.addWidget(business_choices_layout)
    
            hbox = QHBoxLayout()
            hbox.addWidget(pet_layout)
            hbox.addWidget(pet_business_layout)
    
            self.setLayout(hbox)
    

    Note that the code now will hang in the following loop, because you add an element to a list while iterating through that loop. That is something you have to fix yourself.

    for each in self.business_list:
        self.business_list.append(QRadioButton(each)) # infinite recursion here!