简体   繁体   English

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

[英]PyQt4 - Custom widget class structure?

During regular intervals of my program, a block (of 3 stacked) widgets need to be added to a horizontal layout. 在我的程序的定期间隔期间,需要将块(3个堆叠的)小部件添加到水平布局。 Since the widgets within each block are important to eachother, I wish to encapsulate each stack as it's own widget (making the layout adding business much easier). 由于每个块中的小部件对彼此都很重要,我希望将每个堆栈封装为它自己的小部件(使布局更容易添加业务)。

I'm having trouble getting PyQt4 to recognise my 'stack' as a widget. 我无法让PyQt4将我的'堆栈'识别为小部件。

I made the widget stack in Qt Designer (as form: widget) and converted it to a .py via 我在Qt Designer中创建了widget堆栈(作为form:widget)并将其转换为.py via
'pyuic4 DesignerFile.ui > ClassFile.py'. 'pyuic4 DesignerFile.ui> ClassFile.py'。

Now I can't seem to add this 'stack' (parent widget of 3 child widgets) to the layout via .addWidget( Class ). 现在我似乎无法通过.addWidget(Class)将此“堆栈”(3个子窗口小部件的父窗口小部件)添加到布局中。

I tried constructing a super class of the stack class (because I need to add more functionality to the stack) but the instance of the class is either... 我尝试构建堆栈类的超类(因为我需要向堆栈添加更多功能)但是类的实例要么......

  • Not recognised as a widget 不被识别为小部件
  • Invisible 无形
  • defective because I've no idea on how to structure the super class. 有缺陷,因为我不知道如何构建超类。

Here's what I'm failing with at the moment (though it's about the 8th class structure I've tried): 这就是我目前失败的原因(尽管它是关于我尝试过的第8类结构):

from ClassFile import ClassCode

class Stack(ClassCode):
    def __init__(self,parent= None):
        QtGui.QWidget.__init__(self,parent)

Could somebody help me structure this or lead me to some good examples? 有人可以帮我构建这个或者引导我一些好的例子吗?
(I've mimicked the code in both the following sources but with no avail!! (我在以下两个来源中模仿了代码,但没有用!
http://lateral.netmanagers.com.ar/stories/27.html#what-you-need-to-follow-the-tutorial http://lateral.netmanagers.com.ar/stories/27.html#what-you-need-to-follow-the-tutorial
http://zetcode.com/tutorials/pyqt4/customwidgets/ ) http://zetcode.com/tutorials/pyqt4/customwidgets/

Thanks! 谢谢!

Specs: 眼镜:
python 2.7.2 python 2.7.2
PyQt4 PyQt4中
Windows 7 Windows 7的

When you compile a python module from a ui file with the default options, it will (amongst other things) generate a simple "setup" class. 当您使用默认选项从ui文件编译python模块时,它将(除其他外)生成一个简单的“设置”类。 In outline, the setup class will look like this: 概括地说,安装程序类将如下所示:

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

There are a couple of issues to notice here that are relevant to the question. 这里有一些与问题相关的问题需要注意。

Firstly, the setup class is designed to be used as a mixin rather than as a direct subclass. 首先,setup类设计用作mixin而不是直接子类。 It's task is to "inject" ui into a host widget that is passed to the setupUI method. 它的任务是将ui“注入”传递给setupUI方法的主机窗口小部件。

Secondly, the setup class is given an ugly, unpythonic identifier that is created by prepending "Ui_" to the objectName property that was set in Designer. 其次,设置类被给予由前面加上“Ui_”到所创建的一个丑陋,unpythonic标识符objectName这是在设计器来设置属性。

Fortunately, pyuic4 provides a way to bypass these two issues. 幸运的是,pyuic4提供了一种绕过这两个问题的方法。 All that's required is to use the -w option when compiling the python module from the ui file: 所需的只是在从ui文件编译python模块时使用-w选项:

pyuic4 -w designerfile.ui > classfile.py

This will add a wrapper class that (1) can be easily subclassed, and (2) has the class-name that you damn well gave it in Qt Designer. 这将添加一个包装类,(1)可以很容易地进行子类化,并且(2)具有在Qt Designer中很好地给出它的类名。

The wrapper class will look something like this: 包装类看起来像这样:

class ClassCode(QtGui.QWidget, Ui_ClassCode):
    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
        QtGui.QWidget.__init__(self, parent, f)

        self.setupUi(self)

As you can see, it doesn't do anything special: you could easily replicate what it does in your own code. 正如您所看到的,它没有做任何特别的事情:您可以轻松地复制它在您自己的代码中执行的操作。 But, IMO, it does make the compiled modules much more intuitive to use. 但是,IMO确实使编译后的模块更加直观易用。

For example: 例如:

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)

First, it's more appropriate to call the parent __init__ with the use of super . 首先,使用super调用父__init__更合适。 That will ensure the method in the proper super class is invoked. 这将确保调用适当的超类中的方法。 Second, when using a class constructed with pyuic, you need to call self.setupUi(self) from your __init__ method. 其次,当使用由pyuic构造的类时,需要从__init__方法调用self.setupUi(self) And lastly, you need to make sure and multiple inherit from both the proper Qt class and the pyuic generated class (which is really more of a mixin). 最后,你需要确保和多次继承适当的Qt类和pyuic生成的类(这实际上更像是mixin)。

So, something like this: 所以,像这样:

from ClassFile import ClassCode

class Stack(QtGui.QWidget, ClassCode):
    def __init__(self,parent= None):
        super(Stack, self).__init__(parent)
        self.setupUi(self)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM