PyQt4 - 自定义小部件类结构?

6
在我的程序的常规间隔内,需要向水平布局添加一组(3个堆叠)小部件。由于每个块内的小部件对彼此很重要,我希望将每个堆栈封装为自己的小部件(使布局添加业务更容易)。
我在Qt Designer中制作了小部件堆栈(形式:小部件),并通过 'pyuic4 DesignerFile.ui> ClassFile.py' 将其转换为 .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-tutorial
http://zetcode.com/tutorials/pyqt4/customwidgets/

谢谢!

规格:
python 2.7.2
PyQt4
Windows 7

2个回答

5

当你使用默认选项从ui文件编译python模块时,它将会生成一个简单的"setup"类,其中包括其他内容。简要概述,setup类如下:

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

这里有几个问题需要注意,这些问题与问题相关。

首先,设置类旨在用作mixin而不是直接子类。它的任务是将ui“注入”到传递给setupUI方法的主机小部件中。

其次,为了创建不雅观的、非pythonic的标识符,设置类会在Designer中设置了objectName属性之前使用"Ui_"。

幸运的是,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)

正如你所看到的,它并没有做什么特殊的事情:你可以很容易地在自己的代码中复制它所做的。但是,在我看来,它确实使编译后的模块更加直观易用。

例如:

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('猫') - Anti Earth
1
@AntiEarth。当然可以:您可以设计自己的Stack子类,就像子类化任何其他Qt小部件一样。因此,Stack.__init__的签名可以更改为例如__init__(self, name, parent=None) - ekhumoro

1

首先,更合适的做法是使用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)

1
他实际上应该首先从所需的QWidget继承,然后从由pyuic生成的ClassCode继承。 - jdi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接