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

时间:2011-12-17 12:09:12

标签: python pyqt pyqt4 qt-designer custom-widgets

在我的程序的常规间隔期间,需要将块(3个堆叠的)小部件添加到水平布局。由于每个块中的小部件对彼此都很重要,我希望将每个堆栈封装为它自己的小部件(使布局更容易添加业务)。

我无法让PyQt4将我的'堆栈'识别为小部件。

我在Qt Designer中创建了小部件堆栈(作为form:小部件)并通过
将其转换为.py 'pyuic4 DesignerFile.ui> ClassFile.py”。

现在我似乎无法通过.addWidget(Class)将这个'stack'(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 个答案:

答案 0 :(得分:5)

当您使用默认选项从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方法的主机窗口小部件。

其次,setup类被赋予一个丑陋的unpythonic标识符,该标识符是通过将“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)

答案 1 :(得分:1)

首先,使用__init__调用父super更合适。这将确保调用适当的超类中的方法。其次,当使用由pyuic构造的类时,您需要从self.setupUi(self)方法调用__init__。最后,你需要确保和多次继承适当的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)