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 分离导致功能无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章