Python – Using QTDesigner with PyQT and Python 2.6

pyqt4pythonqt-designerqt4

I'm new to Python and am starting to teach myself GUI programming (hopefully) using PyQT4.7 and Python 2.6

I just downloaded the whole PyQT/QT4 package (including QTDesigner) from the PyQT website, however it seems QTDesigner, which looks amazing to use as a newbie (since you can see all the attributes/properties/defaults etc) of each widget and visually edit the properties is great, but PyQT seems not to set QTDesigner to integrate directly with with PyQT and PyQTs python code generation scripts:

i.e.: Hitting "View Code", tries to run the Designer->C++ script called (uic) instead of the pyuic.py script, etc.

Is there a way to get QTDesigner to integrate closely with PyQT for code generation on the fly like it does with C++?

If not, does that mean I have to code the entire QT GUI within my Python IDE and lookup all the documentation and boilerplate code for every widget? (seems very inefficient and inelegant compared to just having QTDesigner+Python integration).

What is the customary toolchain//production flow of using Designer with PyQT? (If no direct integration is possible — do python+pyQT users just skip using QTDesigner all together and manually write all the QT GUI code in python?)

Any additional tips/suggestions for a PyQT newbie would be appreciated. Thanks!

ps I know a bunch of you are probably going to tell me to just suck it up and code all the QT UI by hand, but if I use Designer while learning as asked above, please provide a way to do that so I can learn it more easily, thanks!

Best Answer

I started to write my first PyQT application (PyQT is used only to handle GUI), and it seems, that good toolchain is: QtDesigner to generate .ui s and handle resources and some IDE, that can set QtDesigner to edit those. I use Eclipse, cause it is highly customisable. You can compile your .qrc and .ui by demand by doing somewhat like this at application start, or at setup, or any other time:

os.system("pyrcc4.exe -o ui/images_rc.py ui/images/images.qrc")
uic.compileUiDir(appDir + '/ui', True)

and then using generated classes this way:

class MyMainWindow(QtGui.QMainWindow):

    def __init__(self, owner):
        QtGui.QMainWindow.__init__(self)
        # 'Ui_MyMainWindow' is the class, that was generated by uic, 
        # naming convention is: 'Ui_' plus the name of root widget in designer
        self.ui = Ui_MyMainWindow()
        self.ui.setupUi(self)

or you can load .ui directly when container inits:

    QtGui.QMainWindow.__init__(self)
    self.ui = None
    uic.loadUi('MyMainWindowUI.ui', self.ui)
    #now you have the instance of Ui_MyMainWindow in self.ui too, as above

note, that I have added UI suffix to .ui file's name, it was done to avoid name intersection , cause name of .py file, generated by uic, is not class name starting with 'Ui_', but just root widget's one.

And another one note: at the end of generated file uic places 'import %.qrc name%_rc' (by default is import images_rc) string, so you must aware this when using pyrcc4.

The whole approach is flexible enough, it takes all dummy ui coding work from you; but you still can do some fine tuning in MyMainWindow.ui attribute, where the instance of Ui_MyMainWindow lays; and it avoids unneeded inheritance. Personally, I make _connectSlots and _initIntefrace methods in MyMainWindow to do some work designer cannot.

Still I have to note that writing interface code by yourself is good approach, cause the code, generated by uic, is UGLY. I prefer to load .ui in place by loadUi() because of this :) And if you have a lot of custom PyQT controls, it is so booooring to bring them into QtDesigner..