Qt Designer和Python在单独的functions.py中运行一个函数[重复]
Posted
技术标签:
【中文标题】Qt Designer和Python在单独的functions.py中运行一个函数[重复]【英文标题】:Qt Designer and Python run a function in separate functions.py [duplicate] 【发布时间】:2021-12-07 16:33:50 【问题描述】:我是 python 新手。我在 QtDesigner 中设计了一个 GUI,并翻译了代码以将其与 python 一起使用。因为如果我在 GUI 中更改某些内容,它会覆盖我的代码,我想为函数使用单独的文件。
代码应该在显示主窗口后运行,但出现错误
Ui_MainWindow' 对象没有属性 'fillContactList'
如果有人能帮助我,我将不胜感激。
import sys
import psycopg2
from PySide6 import (QtCore, QtWidgets, QtGui)
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QLabel, QMainWindow, QMenuBar,
QSizePolicy, QStatusBar, QTabWidget, QWidget)
from mainwindow import Ui_MainWindow
class mainwindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(mainwindow, self).__init__()
self.setWindowTitle("Skills In Motion")
def fillContactList(self):
conn = psycopg2.connect(database="CRM", user="********", password="*****", host="localhost", port=5432)
cur = conn.cursor()
dataset = cur.execute("SELECT cust_name, cust_pk FROM customer")
results = cur.fetchall()
rowPosition = 0
for customers in results:
self.contactsTable.insertRow(rowPosition)
self.contactsTable.setItem(rowPosition,0,QtWidgets.QTableWidgetItem(customers[0]))
self.contactsTable.setItem(rowPosition,1,QtWidgets.QTableWidgetItem(str(customers[1])))
self.contactsTable.hideColumn(1)
rowPosition = rowPosition+1
self.contactsTable.itemSelectionChanged.connect(self.onSelectionContact)
self.contactsTable.selectRow(0)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
ui.fillContactList()
MainWindow.show()
sys.exit(app.exec())```
【问题讨论】:
您没有使用您创建的mainwindow
类。删除app = ...
之后直到最后一行的行,并将它们替换为mainWindow = mainwindow()
mainWindow.fillContactList()
和mainWindow.show()
。此外,您应该将类更改为MainWindow
(并相应地更改上述内容),因为类(作为常量)应始终具有大写的名称。
【参考方案1】:
首先,您应该将 mainwindow
类重命名为 MainWindow
。
MainWindow
只需要从 QMainWindow
继承。
创建Ui_MainWindow
对象后,使用其setupUi
方法来构建您的MainWindow
对象。
您在设计器中创建的所有小部件引用都将作为Ui_MainWindow
对象的属性提供。
所以,将其存储在 主窗口 中作为self.ui = Ui_MainWindow()
。将主窗口构建为self.ui.setupUi(self)
。引用任何小部件,如self.ui.contactsTable
您需要创建 MainWindow
类的对象,而不是 QMainWindow
试试这样:
import sys
from PySide6.QtWidgets import QMainWindow, QApplication
from mainwindow import Ui_MainWindow
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Skills In Motion")
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.fillContactList()
def fillContactList(self):
# Reference Table like this
# self.ui.contactsTable
pass
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
【讨论】:
"MainWindow 只需要从 QMainWindow 子类化"。这是不准确的。多重继承允许使用self.setupUi(self)
,并且使用基实例也可以直接引用UI,所以你可以直接使用self.someWidget
而不是self.ui.someObject
:因为生成的表单类是一个非常简单的python对象,所以它赢了'不会产生任何命名冲突(只要您不使用“错误”小部件名称,这可能会覆盖现有的类函数,但如果您明智地选择名称,那将永远不会发生)。
@musicamante 是的,我同意你的看法。我实际上是在对我给出的示例进行解释。就个人而言,我喜欢这种方法,因为它使命名空间保持独立。我应该在答案中提到它。感谢您指出这一点
分离命名空间本身并没有错,相反,但我们也不应该忘记对严格(和正确)编程模式的实用性:好的做法并不总是正确的做法.拥有ui
对象可以提供更好的封装,但实际上在编码方面几乎没有什么好处:只要实例是Qt 小部件,它的所有子小部件都是它的直接属性是有意义的;如果我们要对层次结构更加严格,我们也应该在名称上使用层次结构,但我们知道它的弊端多于好处,尤其是 ->
-> 考虑到 Qt 对象可以通过编程方式重新设置父级;因为拥有像self.topFrame.leftGroup.topLeftButton
这样的孙子小部件几乎没有什么好处,结果是也拥有self.ui.topLeftButton
并不比直接拥有像self.topLeftButton
这样的更具可读性和直接的引用好多少。此外,由于基类本身就是一个小部件(因此,它是一个与 UI 相关的对象),所以拥有一个单独的 ui 对象无论如何都没有多大意义。以上是关于Qt Designer和Python在单独的functions.py中运行一个函数[重复]的主要内容,如果未能解决你的问题,请参考以下文章
无法启动 Maya 集成的 qt designer 的解决方法和原因 以及 中英文切换
为啥qt designer设计界面和用python运行得到的不一样?
第15.13节 PyQt(Python+Qt)入门学习:Qt Designer的Spacers部件详解