具有自定义插槽的PyQt5 Designer

问题描述 投票:1回答:2

我还在试图找出PyQt并遇到另一个问题,我在过去的几个小时里一直在打扰我。当我使用pyuic5将.ui文件转换为.py文件时,部分输出(在类Ui_MainWindow中)将信号连接到插槽:

self.browseButton.clicked.connect(MainWindow.browseSlot)
self.importButton.clicked.connect(MainWindow.importSlot)
self.lineEdit.returnPressed.connect(MainWindow.returnPressedSlot)

这是从main函数调用的:

def main():
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = MainWindowUI()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

在此之上,在同一个文件中,我有以下代码:

class MainWindowUI(Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.model = Model()

    def setupUi(self, mainWindow):
        super().setupUi(mainWindow)

    def debugPrint(self, msg):
        self.textEdit.append(msg)

    def refreshAll(self):
        self.lineEdit.setText(self.model.getFileName())
        self.textEdit.setText(self.model.getFileContents())

    def returnPressedSlot(self):
        self.debugPrint('Return key pressed')

    def importSlot(self):
        self.debugPrint('Import button pressed')

    def browseSlot(self):
        self.debugPrint('Browse button pressed')

我得到的确切错误是这样的:

AttributeError: 'QMainWindow' object has no attribute 'browseSlot'

这实际上非常有意义,因为QtWidgets.QMainWindow()没有理由知道我在MainWindowUI类中定义的自定义插槽。因此,它不起作用是有道理的,但我对我应该采取的不同做法感到困惑。这就是我所见过的每一个教程都是如此设置的,所以很明显我在某处有一个基本的误解。任何帮助澄清这个问题将不胜感激!

提前谢谢了。


编辑添加我的Ui_MainWindow类的完整代码:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'test.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(798, 593)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.tab)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.frame_2 = QtWidgets.QFrame(self.tab)
        self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_2.setObjectName("frame_2")
        self.debugTextBrowser = QtWidgets.QTextBrowser(self.frame_2)
        self.debugTextBrowser.setGeometry(QtCore.QRect(10, 10, 351, 461))
        self.debugTextBrowser.setObjectName("debugTextBrowser")
        self.horizontalLayout_2.addWidget(self.frame_2)
        self.frame = QtWidgets.QFrame(self.tab)
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.browseButton = QtWidgets.QPushButton(self.frame)
        self.browseButton.setGeometry(QtCore.QRect(80, 30, 51, 20))
        self.browseButton.setObjectName("browseButton")
        self.lineEdit = QtWidgets.QLineEdit(self.frame)
        self.lineEdit.setGeometry(QtCore.QRect(80, 10, 281, 20))
        self.lineEdit.setObjectName("lineEdit")
        self.importButton = QtWidgets.QPushButton(self.frame)
        self.importButton.setGeometry(QtCore.QRect(310, 30, 51, 20))
        self.importButton.setObjectName("importButton")
        self.textEdit = QtWidgets.QTextEdit(self.frame)
        self.textEdit.setGeometry(QtCore.QRect(80, 130, 281, 81))
        self.textEdit.setObjectName("textEdit")
        self.horizontalLayout_2.addWidget(self.frame)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.setupProgressBar = QtWidgets.QProgressBar(self.tab)
        self.setupProgressBar.setProperty("value", 0)
        self.setupProgressBar.setTextVisible(False)
        self.setupProgressBar.setInvertedAppearance(False)
        self.setupProgressBar.setTextDirection(QtWidgets.QProgressBar.TopToBottom)
        self.setupProgressBar.setObjectName("setupProgressBar")
        self.verticalLayout.addWidget(self.setupProgressBar)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.tabWidget.addTab(self.tab_2, "")
        self.tab_3 = QtWidgets.QWidget()
        self.tab_3.setObjectName("tab_3")
        self.tabWidget.addTab(self.tab_3, "")
        self.tab_4 = QtWidgets.QWidget()
        self.tab_4.setObjectName("tab_4")
        self.tabWidget.addTab(self.tab_4, "")
        self.tab_5 = QtWidgets.QWidget()
        self.tab_5.setObjectName("tab_5")
        self.tabWidget.addTab(self.tab_5, "")
        self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 798, 18))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        self.browseButton.clicked.connect(MainWindow.browseSlot)
        self.importButton.clicked.connect(MainWindow.importSlot)
        self.lineEdit.returnPressed.connect(MainWindow.returnPressedSlot)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.browseButton.setText(_translate("MainWindow", "Browse"))
        self.importButton.setText(_translate("MainWindow", "Import"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Setup"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Production Forecast"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Production Forecast"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("MainWindow", "Page"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _translate("MainWindow", "Page"))
python pyqt pyqt5 qt-designer
2个回答
1
投票

PyQt建议您在docs中继承相应的小部件,在本例中为QMainWindow,并使用Ui_MainWindow作为接口,建议您使用装饰器@QtCore.pyqtSlot(),因为您节省了资源并避免了信号过载的问题。

class MainWindowUI(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.model = Model()

    def setupUi(self, mainWindow):
        super().setupUi(mainWindow)

    def debugPrint(self, msg):
        self.textEdit.append(msg)

    def refreshAll(self):
        self.lineEdit.setText(self.model.getFileName())
        self.textEdit.setText(self.model.getFileContents())

    @QtCore.pyqtSlot()
    def returnPressedSlot(self):
        self.debugPrint('Return key pressed')

    @QtCore.pyqtSlot()
    def importSlot(self):
        self.debugPrint('Import button pressed')

    @QtCore.pyqtSlot()
    def browseSlot(self):
        self.debugPrint('Browse button pressed')

def main():
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindowUI()
    w.show()
    sys.exit(app.exec_())

if __name__ == '__main__': main()

0
投票

PyQt 5 Designer生成扩展名为.ui的文件。该文件包含xml代码,可以使用pyuic5命令将其转换为Python代码。 pyuic5命令生成扩展名为.py的文件。

但每次运行pyuic5命令时,它都会覆盖对Python文件所做的任何更改。为了防止这种情况,我们需要将生成的Python文件中的“main”代码复制到一个单独的文件中,然后将此文件用作我们的主程序文件。在这个文件中,我们可以导入pyuic5命令生成的Python类。我们还可以在此文件中添加自定义插槽

将Qt Designer代码与自定义代码分离的这种做法是很好的Qt编程实践。视频电子书的第3节有人建议:“qazxsw poi”。

© www.soinside.com 2019 - 2024. All rights reserved.