During regular intervals of my program, a block (of 3 stacked) widgets need to be added to a horizontal layout. 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.
I made the widget stack in Qt Designer (as form: widget) and converted it to a .py via
'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 ).
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):
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://zetcode.com/tutorials/pyqt4/customwidgets/ )
Thanks!
Specs:
python 2.7.2
PyQt4
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. 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. It's task is to "inject" ui into a host widget that is passed to the setupUI
method.
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.
Fortunately, pyuic4 provides a way to bypass these two issues. All that's required is to use the -w
option when compiling the python module from the ui file:
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.
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.
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
. 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. 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).
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With