PyQt5 - 将逻辑与 ui 分离导致功能无法正常工作

Posted

技术标签:

【中文标题】PyQt5 - 将逻辑与 ui 分离导致功能无法正常工作【英文标题】:PyQt5 - Separating logic from ui leads to functions not working 【发布时间】:2020-03-02 15:12:48 【问题描述】:

我试图将我的程序的功能与 Ui 类(由 PyQt5 设计器生成)分开,指定为 here 和 here。 问题是当运行 logic.py 时 Ui 出现了,但程序的功能根本不起作用。 我正在使用 PyCharm,所以我尝试使缓存无效,安装 pyqt5-stubs 但效果不佳。任何帮助将不胜感激!

ui.py

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("File Manager")
        MainWindow.resize(1120, 800)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.button1 = QtWidgets.QPushButton(self.centralwidget)
        self.button1.setGeometry(QtCore.QRect(10, 80, 121, 41))

        self.listView = QtWidgets.QListView(self.centralwidget)
        self.listView.setGeometry(QtCore.QRect(10, 190, 221, 471))
        self.listView.setObjectName("listView")
        path = r"C:\Test_folder"
        self.dirModel = QtWidgets.QFileSystemModel()
        self.dirModel.setRootPath(QtCore.QDir.rootPath())
        self.listView.setModel(self.dirModel)
        self.listView.setRootIndex(self.dirModel.index(path))


        self.fileModel = QtWidgets.QFileSystemModel()
        self.treeView = QtWidgets.QTreeView(self.centralwidget)
        self.treeView.setModel(self.fileModel)
        self.treeView.setRootIndex(self.fileModel.index(path))
        self.treeView.setGeometry(QtCore.QRect(270, 90, 801, 571))
        self.treeView.setObjectName("treeView")

        MainWindow.setCentralWidget(self.centralwidget)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("File Manager", "File Manager"))
        self.button1.setText(_translate("MainWindow", "+ New File"))

logic.py

from PyQt5.QtWidgets import *
from ui import Ui_MainWindow
import sys

class Logic(Ui_MainWindow):
    def __init__(self):
        super(Ui_MainWindow, self).__init__()

        # Set up the user interface
        self.setupUi(self)

        # "New Project" button function call
        self.button1.clicked.connect(self.make_document)

        # When folder in listView is clicked, the items stored in it are
        # displayed in the treeview.
        self.listView.clicked.connect(self.on_click)

    # Program Functions
    def on_click(self, index):
        """When a directory is selected in the list view, show all of its files
        in the tree view."""
        path = self.dirModel.fileInfo(index).absoluteFilePath()
        self.treeView.setRootIndex(self.fileModel.setRootPath(path))

    def make_document(self):
        print("Making document")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

【问题讨论】:

【参考方案1】:

你犯了一些错误。

首先,您从未创建过Logic 的实例。

然后,为了使用 pyuic 生成的文件,必须创建一个 QWidget,以便可以使用 UI_* 对象在其中构建 UI。

您不需要子类化 Ui_MainWindow,而是您将要使用的小部件类(在您的情况下为 QMainWindow)。然后您可以选择使用单继承或多继承方法,但我建议您使用后者。

单继承:

class Logic(QMainWindow):
    def __init__(self):
        super(Logic, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.button1.clicked.connect(self.make_document)
        # ...

多重继承:

class Logic(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(Logic, self).__init__()

        self.setupUi(self)

        self.button1.clicked.connect(self.make_document)

显然,这意味着在启动应用程序时必须创建 Logic() 实例,而不是 Ui_MainWindow

if __name__ == "__main__":
    app = QApplication(sys.argv)
    logic = Logic()
    logic.show()
    sys.exit(app.exec_())

如需更多了解,请仔细阅读有关using Designer的官方文档。

【讨论】:

您能详细说明您的前两点吗?我正确地实现了继承,但它仍然无法正常工作。否则,我阅读了文档(如上链接),但我仍然无法弄清楚。谢谢。 您是否在if __name__... 语句中创建了Logic() 的实例?请注意,您只需要创建该实例,无需在其中添加 ui = Ui_MainWindow(),因为 Logic 类会处理这些。阅读答案底部的编辑。 啊,是的,我现在明白了,而且效果很好。非常感谢你! :)

以上是关于PyQt5 - 将逻辑与 ui 分离导致功能无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5界面设计与逻辑分离

PyQt5界面设计与逻辑分离

PyQt5界面设计与逻辑分离

PyQt5系列教程如何让界面和逻辑分离

PyQt5中登录界面跳转到不同界面的使用方式

第三篇 -- 界面与逻辑分离的设计方法(多继承方法和单继承方法)