I’ve been searching high and low, trying to dig out the entire internet on this subject for the past few days.

It’s either the version of the Qt designer doesn’t match with what we have,

or the PyQt that they have in the net is not the version of what we are using.

Either way, it was really a pain in the ass, especially for people like me, that are still quite new to python.

After a few days of painful process, and a few trial-and-error, I finally managed to get a grasp on the tip of the ice berg of this whole new things.

This is actually a Qt4 QtDesigner Tutorial, which is actually an upgrade for this Qt3 Tutorial.

And I guess it’s better for me to log it down in my blog, before I forget about the steps.

Here are the setups that I have…

  • Python version 3.1.1
  • PyQt4
  • Qt designer 4.6.0

Here are the things that I’m gonna go thru.

  1. let’s go thru how to use the Qt designer tool to make a simple GUI.
    1. The form has 3 widgets,
      1. a lineEdit widget as an input
      2. a textEdit widget as a display
      3. a pushbutton widget as a clear button to clear the display
  2. Next, we’ll go thru how to generate a Python module class for the GUI that we’ve just created.
  3. Finally, how we come up with a wrapper that uses the module class and call to the form that we’ve just created.

Motivation

The small project that we are gonna achieve here is that

  1. the lineEdit widget (at the bottom) allows us to type something.
  2. when we press the “Enter” key, anything typed in the lineEdit widget will be transfered over and displayed in the textEdit widget.
  3. When the “Clear” pushButton is being pressed, this will clear off any content in the display window of the textEdit.

Creating a GUI Form With Qt Designer

1. Invoke the Qt designer tool.

2. Create an empty widget.

3. This is an empty widget just created.

4. Now, let’s add some widgets to this form.

5. On the left panel, drag-and-drop the pushButton into your form (cool isn’t it? ;)

6. Do the same thing for the lineEdit and textEdit widget.
- you can double click on the widgets and adjust them to your heart’s content.
- you can even double click on them, and change their values.
- here, I’ve double clicked on my pushButton and changed the text to “Clear”

7. And this is the final form looks like.

8. At the top right corner is the Object Inspector window.
- You can change the name of your widgets here by double clicking on them.

9. One last thing to note. Because we will rely on the “Enter” pressing activity in transfering the text from the lineEdit over to the textEdit widget, we can not allow the Enter action to interfere with the default way of how the button receives signal. We should turn off this feature at the Property Editor, and set the autoDefault of the pushButton to False.

10. And we are practically done !

11. Click the File -> Save, and save your form into any name. I named mine gui.ui.

12. Noticed that the form is in a xml format.

Turning Your GUI Form Into A Python Module Class Object

1. This is easy.

2. Python comes with a bundled command called pyuic which specifically does this dirty job for you.

3. Use this script to generate the gui.ui file into a python module class file name gui.py.

4. %pyuic4 gui.ui -o gui.py

5. Take a peek into the gui.py.

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'test/untitled.ui' #
# Created: Thu Apr  8 14:03:13 2010
#      by: PyQt4 UI code generator 4.7 #
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui
class Ui_Form(object):
  def setupUi(self, Form):
    Form.setObjectName("Form")
    Form.setEnabled(True)
    Form.resize(477, 367)
    self.pushButton = QtGui.QPushButton(Form)
    self.pushButton.setGeometry(QtCore.QRect(393, 333, 75, 25))
    self.pushButton.setObjectName("pushButton")
    self.lineEdit = QtGui.QLineEdit(Form)
    self.lineEdit.setGeometry(QtCore.QRect(9, 335, 361, 21))
    ......

6.We don’t need to worry about this file.

7. Actually, the biggest difference in Qt3 and Qt4 design is that, Qt4 is being structured in such a way that, once we’ve completed designing out GUI form, and have it generated into a python module class object thru pyuic4, we shouldn’t be even touching/editting the file !

8. Anything additional, or scripting, should be done outside, in the wrapper. (or at least, that’s my understanding of it)

Writing A Wrapper And Using The Form Module Class

1. Now comes the final step.

2. Which took me almost the past few days banging my head over the wall searching for working methods.

3. First, let’s open a new file call run.py

4. Let’s take a look at what we’ve got here:-

#!/usr/bin/python -d

import sys
from PyQt4 import QtCore, QtGui
from gui import Ui_Form

class MyForm(QtGui.QMainWindow):
  def __init__(self, parent=None):
    QtGui.QWidget.__init__(self, parent)
    self.ui = Ui_Form()
    self.ui.setupUi(self)
    QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL("clicked()"), self.ui.textEdit.clear )
    QtCore.QObject.connect(self.ui.lineEdit, QtCore.SIGNAL("returnPressed()"), self.add_entry)

  def add_entry(self):
    self.ui.lineEdit.selectAll()
    self.ui.lineEdit.cut()
    self.ui.textEdit.append("")
    self.ui.textEdit.paste()

if __name__ == "__main__":
  app = QtGui.QApplication(sys.argv)
  myapp = MyForm()
  myapp.show()
  sys.exit(app.exec_())

5. Line 03 and 04 is the common stuff, importing other libraries into the current ones.

6. Line 05 imports the form class that we’ve generated.

7. From line 08 -> 13, that’s the standard procedure of
- creating a wrapper class which inherits from the QtGui.QMainWindow class.
- instantiating a new instances of our newly generated form object
- calling the instance’s method (setupUi) which setups our form.

8. Line 21 -> 24 is also a standard thingie.
- it starts a new window application
- instantiate a new instance to our newly created wrapper class (MyForm)
- Runs the program.

9. Basically, everything from step 7 to step 8 are standards.

10. All the lines in the run.py are standard templates that every wrapper can use, except line 12 and line 13.

11. QtCore.QObject.connect() is the built-in function that checks for the events that happens in your gui.

12. Basically, the parameters are:-
- QtCore.QObject.connect( sender_widget, signal_received, action/methods )

13. For line 12, we can see that these are the parameters:-
- sender_widget = pushButton
- signal_received = clicked()
- action/method = textEdit->clear()

14. What this means is, whenever the pushButton is being clicked, then the textEdit should be cleared.

15. Line 13 needs more than one single action, thus, we dump it into a function call add_entry.

16. We can see that, when lineEdit widget is being issues with a “returnPressed()” signal:-
- the add_entry() function is being called
- the content of the lineEdit is being selected. (line 16)
- and then cut (line 17)
- and pasted into a new line in the textEdit widget (line18-19)

17. And this is what you will get when you run your program

Honestly, now, I really think that PyQt4, which comes with Qt designer is way much a better combination compared to Perl Tk.

At least, it makes the work of all the GUI form designing more hassle free.

I’ve searched thru the net, but doesn’t seem to find any modules which comes close to the PyQt4 class which binds python so nicely with Qt. (I’m not sure though, maybe there’s one of it lying around there in the midst of the internet world)

Recommended Readings:-



Didn't find what you are looking for?

Trying searching it here ...




  38 Responses to “A Simple Tutorial On GUI Programming Using Qt Designer With PyQt4”

  1. Thanks so much! I too ran into the same problems of no good tutorials. I was up and running within 5minutes of reading this! Nice and clean documentation.


  2. Brian:

    Thanks so much! I too ran into the same problems of no good tutorials. I was up and running within 5minutes of reading this! Nice and clean documentation.

    Glad that it helped :)

  3. Hi lionel,
    many thanks for this tutorial.
    May I suggest to add
    http://www.commandprompt.com/community/pyqt/x1214
    to the Recommended Readings?
    Bye
    marco


  4. marco:

    Hi lionel,
    many thanks for this tutorial.
    May I suggest to add
    http://www.commandprompt.com/community/pyqt/x1214
    to the Recommended Readings?
    Bye
    marco

    Hey marco, that’s a nice site :)
    thx for sharing. It’s in the recommended readings already :)

  5. I think you should repair you module class. It contains error for me.

    You should change this
    import sys from PyQt4
    import QtCore, QtGui
    from gui import Ui_Form

    into this
    import sys
    from PyQt4 import QtGui, QtCore
    from gui import Ui_Form

    that works for me when I’m using WinXP.


  6. nEk0:

    I think you should repair you module class. It contains error for me.
    You should change this
    import sys from PyQt4
    import QtCore, QtGui
    from gui import Ui_Form
    into this
    import sys
    from PyQt4 import QtGui, QtCore
    from gui import Ui_Form
    that works for me when I’m using WinXP.

    Aikss ….. Thanks for the heads up ……
    that’s a mistake. No one ever mentioned that to me.
    I’ve corrected it. Thanks again :)
    Visited your site, and looks like you are a cat person too? :)

  7. lol. My site hosted at slow hosting. Never update nor visit it recently. Kikiki.. I really love cat. You too I think. :)

  8. hey.. I think I messed up with your codes here.. I’m really sorry about this but, my codes are for python 2.x and you using python 3.x.. gomen~.. you can change those codes to their original value.. btw, you don’t need to publish this comment.. it’s kinda embarassing.. kikiki..

  9. Thanks a lot for this clear and easy tutorial, Lionel. :-)

  10. You can definitely see your enthusiasm within the work you write….

    The world hopes for much more passionate writers like you who aren?ˉt scared to say how they believe. Always go best after your heart….

  11. Line 23 [myapp = MyForm() myapp.show()] does not make sense to me, and is returning an error. Am I missing something here?

  12. You should this:

    self.ui.textEdit.document() to get access to the underlying document

    and if you say:
    text = self.ui.textEdit.document().toPlainText()

    you can get a string of the documents contents.
    Do you know of a better (i.e. more efficient) way to save the document as a plain text document? I couldn’t find it.

  13. I’m also new to pyqt and Qt, but need to write a small UI for some heavy numerical computation program.
    Surprisingly cannot find a good intro into pyqt4.
    Why don’t you write that you wanted to upgrade this tutorial http://www.cs.usfca.edu/~afedosov/qttut/
    written for Qt3. Actually I don’t like that you added the function AddEntry() by hands, could not you use Slot Editor in qtDesigner?

    • Hi Alex,
      Didn’t really thought about it when I added the AddEntry() def. I guess it could be done like what u mentioned too. :)
      Ok. I think i should put that into my original post. I’ve added it. Thx for bringing that out to me :)

  14. from gui import Ui_form
    python gives me a error ” cant import name”
    i am using python 2.6.5 in opensuse 11.3 with Qt designer 4.6.0 and pyqt4

  15. Thank you so much. This is the easiest tutorial i have seen so far. Very nicely explained.

  16. I’m still looking. Everyone describes the main window, the dialogs, all kinds of other stuff, but they never show the main window and the dialogs all together integrated.

  17. thanks for this tutorial. very good.
    question
    is there a problem if

    class my_form(QDialog, Ui_form):
    def __init__(self, parent=None):
    QDialog.__init__(self, parent)
    self.setupUi(self)

    def AddEntry(self):
    e=self.lineEdit1.text()
    self.listbox1.addItem(e)
    self.lineEdit1.clear()

    and I don’t have self.ui ?

    Thx !!

  18. first:
    not necessary, just convenient to get rid of the ‘ui’ member.
    in this way the lines:

    QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL(“clicked()”), self.ui.textEdit.clear )
    QtCore.QObject.connect(self.ui.lineEdit, QtCore.SIGNAL(“returnPressed()”), self.add_entry)

    and other connect SIGNAL’s
    can, also, be made in QtDesigner

    second:
    I am new in Qt and I want to know if there are problems if
    i use this way.

  19. hi, i am new to this and i am using pyqt designer to build an GUI. and i got struck in call back functions like outputting program by pressing some buttons please help me out of this.

  20. 2) and help me out of this problem too…… if i write some data that saves the contents of the list box to a file on exit, and then loads the data from the file at startup.

  21. Thank’s =D
    It’s a great tutorial, I have been working and reading with 3 books but get lost with the versions of Python and Qt differences, your tutorial work like a charm.

  22. hi,

    Very good tutorial, even for a french noob who speaks english like a …. :D

 Leave a Reply

(required)

(required)


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

   

Visitors Since Nov 2009

© 2012 Lionel's Blog Suffusion theme by Sayontan Sinha