PyQt4 - 自定义小部件类结构?
Posted
技术标签:
【中文标题】PyQt4 - 自定义小部件类结构?【英文标题】:PyQt4 - Custom widget class structure? 【发布时间】:2011-12-17 12:09:12 【问题描述】:在我的程序的定期间隔中,需要将一个块(3 个堆叠的)小部件添加到水平布局中。由于每个块中的小部件对彼此都很重要,因此我希望将每个堆栈封装为它自己的小部件(使布局添加业务更容易)。
我无法让 PyQt4 将我的“堆栈”识别为小部件。
我在 Qt Designer 中制作了小部件堆栈(作为形式:小部件)并通过将其转换为 .py 'pyuic4 DesignerFile.ui > ClassFile.py'。
现在我似乎无法通过 .addWidget( Class ) 将此“堆栈”(3 个子小部件的父小部件)添加到布局中。
我尝试构建堆栈类的超类(因为我需要向堆栈添加更多功能)但是该类的实例是......
不被识别为小部件 不可见 有缺陷,因为我不知道如何构造超类。这是我目前失败的地方(尽管这是我尝试过的第 8 类结构):
from ClassFile import ClassCode
class Stack(ClassCode):
def __init__(self,parent= None):
QtGui.QWidget.__init__(self,parent)
有人可以帮我构建这个结构或引导我找到一些好的例子吗? (我在以下两个来源中都模仿了代码,但没有成功!!http://lateral.netmanagers.com.ar/stories/27.html#what-you-need-to-follow-the-tutorialhttp://zetcode.com/tutorials/pyqt4/customwidgets/)
谢谢!
规格: 蟒蛇 2.7.2 PyQt4 视窗 7
【问题讨论】:
【参考方案1】:当您使用默认选项从ui
文件编译python 模块时,它将(除其他外)生成一个简单的“设置”类。概括地说,安装程序类将如下所示:
class Ui_ClassCode(object):
def setupUi(self, ClassCode):
ClassCode.setObjectName("ClassCode")
# bunch of boiler-plate ui code goes here
self.retranslateUi(ClassCode)
QtCore.QMetaObject.connectSlotsByName(ClassCode)
def retranslateUi(self, ClassCode):
pass
这里有几个与问题相关的问题需要注意。
首先,setup 类被设计为用作 mixin 而不是直接子类。它的任务是将 ui “注入”到传递给 setupUI
方法的主机小部件中。
其次,设置类被赋予一个丑陋的、非pythonic的标识符,该标识符是通过将“Ui_”添加到在 Designer 中设置的objectName
属性来创建的。
幸运的是,pyuic4 提供了绕过这两个问题的方法。从 ui 文件编译 python 模块时,只需使用-w
选项:
pyuic4 -w designerfile.ui > classfile.py
这将添加一个包装器类,它 (1) 可以很容易地被子类化,并且 (2) 具有您在 Qt Designer 中该死的给它的类名。
包装类看起来像这样:
class ClassCode(QtGui.QWidget, Ui_ClassCode):
def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
QtGui.QWidget.__init__(self, parent, f)
self.setupUi(self)
如您所见,它并没有做任何特别的事情:您可以轻松地在自己的代码中复制它所做的事情。但是,IMO 确实使编译后的模块使用起来更加直观。
例如:
from PyQt4 import QtGui, QtCore
from classfile import ClassCode
class Stack(ClassCode):
def __init__(self, parent=None):
ClassCode.__init__(self, parent)
class Window(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.stack = Stack(self)
self.setCentralWidget(self.stack)
【讨论】:
是否可以将字符串传递给构造函数(实例化小部件时)以通过小部件使用?例如:x = Stack('cat') @AntiEarth。当然:你可以用你喜欢的任何方式设计你的Stack
子类——就像对任何其他 Qt 小部件进行子类化一样。因此Stack.__init__
的签名可以更改为例如__init__(self, name, parent=None)
.【参考方案2】:
首先,使用super
调用父级__init__
更合适。这将确保调用正确的超类中的方法。其次,当使用由 pyuic 构建的类时,您需要从您的 __init__
方法中调用 self.setupUi(self)
。最后,您需要确保从正确的 Qt 类和 pyuic 生成的类(实际上更像是一个 mixin)中多重继承。
所以,是这样的:
from ClassFile import ClassCode
class Stack(QtGui.QWidget, ClassCode):
def __init__(self,parent= None):
super(Stack, self).__init__(parent)
self.setupUi(self)
【讨论】:
他其实应该是先从想要的QWidget继承,再从pyuic生成的ClassCode继承以上是关于PyQt4 - 自定义小部件类结构?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不导入自定义小部件类包的情况下使用自定义小部件和 uic.loadUi?
我需要哪些 Qt 小部件才能使用只读、可滚动的项目列表(pyqt4)