[英]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... 我尝试构建堆栈类的超类(因为我需要向堆栈添加更多功能)但是类的实例要么......
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.