必须在 QWidget Pyqt5 之前构造 QApp

Posted

技术标签:

【中文标题】必须在 QWidget Pyqt5 之前构造 QApp【英文标题】:must construct QApp before QWidget Pyqt5 【发布时间】:2018-01-02 10:01:05 【问题描述】:

我启动了新的 PyQt5 程序,但遇到错误“必须在 QWidget 之前构造 QApplication”。

我理解错误,但没有找到我的代码首先构造我的 QWidget 的位置。

这是我的代码:

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

如果你有任何想法,我很高兴!

新年快乐,享受你的代码:)。

感谢提前

【问题讨论】:

【参考方案1】:

您的代码没有正确缩进。 Main 类中 # Pet form 之后的所有行都应该缩进两次(即 8 个空格),以便它们是 __init__ 构造函数的一部分。这样它会在你创建Main() 类型的对象时执行,这应该在你创建QApplication 对象之后执行。

目前它只缩进一次(即 4 个空格),这意味着它是类定义的一部分。因此,这些行在类定义期间执行,在您创建 QApplication 对象之前。因此出现错误消息。

修复很简单,只需像这样缩进代码:

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)

请注意,代码现在将挂在下面的循环中,因为您在迭代该循环时将元素添加到列表中。这是你必须自己解决的问题。

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

【讨论】:

谢谢,它正在工作。我需要为 groupbox 列表找到另一个解决方案 ;)

以上是关于必须在 QWidget Pyqt5 之前构造 QApp的主要内容,如果未能解决你的问题,请参考以下文章

QWidget:在VS Release模式下必须在QPaintDevice之前构造一个QApplication

必须在传递给 C 运行时函数的 QWidget 和无效参数之前构造一个 QApplication

PyQt5 样式表用于 QWidget 的孩子更改 QWidget

乘以继承自 QWidget 和另一个基类?

PyQt5 - 在 QMainMenu 中,如何使 QWidget 成为父级(暂时)?

QWidget 无法在 QMainWindow 实例 PyQt5 上显示