面向对象风格的Qt.ui文件Python代码生成器?
我想知道如何从使用QtDesigner创建的.ui文件生成OOP风格的Python代码 我想说的是,pyuic4生成的代码不是OOP风格的:小部件不会成为QtGui类的子类。代码很难阅读和扩展 我想要封装所有子部件、布局和函数的类 让我们看一个简单的例子。此主窗口包含一个滑块和一个lcd显示屏,它们以明显的方式连接在一起 首先,这是pyuic4生成的代码:面向对象风格的Qt.ui文件Python代码生成器?,python,qt,oop,pyqt,pyuic,Python,Qt,Oop,Pyqt,Pyuic,我想知道如何从使用QtDesigner创建的.ui文件生成OOP风格的Python代码 我想说的是,pyuic4生成的代码不是OOP风格的:小部件不会成为QtGui类的子类。代码很难阅读和扩展 我想要封装所有子部件、布局和函数的类 让我们看一个简单的例子。此主窗口包含一个滑块和一个lcd显示屏,它们以明显的方式连接在一起 首先,这是pyuic4生成的代码: from PyQt4 import QtCore, QtGui class Ui_MainWindow(object): def
from PyQt4 import QtCore, QtGui
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(268, 186)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtGui.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.horizontalSlider = QtGui.QSlider(self.centralwidget)
self.horizontalSlider.setOrientation(QtCore.Qt.Vertical)
self.horizontalSlider.setObjectName("horizontalSlider")
self.gridLayout.addWidget(self.horizontalSlider, 0, 1, 1, 1)
self.lcdNumber = QtGui.QLCDNumber(self.centralwidget)
self.lcdNumber.setObjectName("lcdNumber")
self.gridLayout.addWidget(self.lcdNumber, 0, 2, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 268, 25))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QObject.connect(self.horizontalSlider, QtCore.SIGNAL("valueChanged(int)"), self.lcdNumber.display)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
我手动将其编辑为我想要的样式:
from PyQt4 import QtCore, QtGui
class MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setObjectName("MainWindow")
self.resize(268, 186)
self.centralwidget = QtGui.QWidget(self)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtGui.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.horizontalSlider = QtGui.QSlider(self.centralwidget)
self.horizontalSlider.setOrientation(QtCore.Qt.Vertical)
self.horizontalSlider.setObjectName("horizontalSlider")
self.gridLayout.addWidget(self.horizontalSlider, 0, 1, 1, 1)
self.lcdNumber = QtGui.QLCDNumber(self.centralwidget)
self.lcdNumber.setObjectName("lcdNumber")
self.gridLayout.addWidget(self.lcdNumber, 0, 2, 1, 1)
self.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(self)
self.menubar.setGeometry(QtCore.QRect(0, 0, 268, 25))
self.menubar.setObjectName("menubar")
self.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(self)
self.statusbar.setObjectName("statusbar")
self.setStatusBar(self.statusbar)
self.retranslateUi()
QtCore.QObject.connect(self.horizontalSlider, QtCore.SIGNAL("valueChanged(int)"), self.lcdNumber.display)
QtCore.QMetaObject.connectSlotsByName(self)
def retranslateUi(self):
self.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
这个可以由代码生成器来完成,而无需进行枯燥的编辑。我的问题是:有这样的代码生成器吗?您可以改用多重继承(有关可能的方法,请参阅): 然而,这两种方法都是OOP风格的。它们各有利弊
不要读取或编辑自动生成的文件 您甚至不必从ui文件生成python文件:使用模块
不应修改自动生成的文件。“代码很难阅读和扩展”不成立,因为你根本不应该触碰该代码。
pyuic
生成的输出将用作父类。在您的情况下,您需要执行类主窗口(QMainWindow,Ui\u MainWindow):
然后在初始化中调用设置Ui(self)
,您就完成了。无需查看生成的代码。@Bakuriu,谢谢您的回答!:)类主窗口(QMainWindow,Ui\u MainWindow)
令人惊讶,但非常出色!我不明白为什么这是“非面向对象风格”。一个好的OOP设计规则是支持组合而不是继承,这正是uic所做的。当前模式实际上是故意在Qt4中引入的,而Qt3中生成的小部件是子类。更多信息请参见。@Frank,直到Bakuriu告诉我多重继承的使用,我才看到OO的可能性。现在我明白了。好吧,我必须承认我以前使用过wxWidgets…:-(请不要开枪。)谢谢你们!))还有一个愚蠢的问题:你们如何从QT设计器中读取UIO文件?(您不能记住所有的东西,是吗?)我使用C++代码的自动完成(在Qt创建者中)。。我不知道如何让它在Python上工作,但我认为可能有办法。@user3202179。我确保为我感兴趣的所有小部件重置objectName
属性,并为我的所有PyQt应用程序使用一致的命名样式。当然,自动完成也有帮助;-)@user3202179我在designerUnless中设置了它们,除非我丢失了它们例如,我认为您的示例应该是self.ui=uic.loadUI(…)和'self.ui.okButton.clicked.connect(self.accept)
@三个菠萝。您缺少了一些东西:loadUI
的baseinstance
参数(在本例中是self
)。它绕过了通常的setupUi
锅炉板废话,直接将ui注入传入的实例中。@ekhumoro哦……我不得不滚动查看,没有注意到正在使用baseinstance参数。哎呀!
from PyQt4.QtGui import QDialog
from ui_imagedialog import Ui_ImageDialog
class ImageDialog(QDialog, Ui_ImageDialog):
def __init__(self):
QDialog.__init__(self)
# Set up the user interface from Designer.
self.setupUi(self)
# Make some local modifications.
self.colorDepthCombo.addItem("2 colors (1 bit per pixel)")
# Connect up the buttons.
self.okButton.clicked.connect(self.accept)
self.cancelButton.clicked.connect(self.reject)
import os
from PyQt4 import QtGui, QtCore, uic
class MyMainWindow(QtGui.QMainWindow):
def __init__(self, parent):
QtGui.QMainWindow.__init__(self, parent)
# We want to inheritate from MyMainWindow.ui
uic.loadUi(os.path.join(os.path.dirname(os.path.abspath(__file__)),"MyMainWindow.ui"), self)
# All widgets are available as classic attributes:
self.okButton.clicked.connect(self.accept)