Friday 8 January 2010

Simple PySide / PyQt tutorial, aimed at Maemo development

I recently met an acquaintance around Maemo (hi Khertan!) who was having problems coming to grips with how to use Qt in general. He's a python developer currently, with exposure to Gtk+, so I thought I'd write up some help for him to read over.

I hope they help you, with whatever you're struggling with! :)

The Code
--------

# Written by Robin Burchell  
# No licence specified or required, but please give credit where it's due, and please let me know if this helped you.
# Feel free to contact with corrections or suggestions.
#
# We're using PySide, Nokia's official LGPL bindings.
# You can however easily use PyQt (Riverside Computing's GPL bindings) by commenting these and fixing the appropriate imports.
from PySide.QtCore import *
from PySide.QtGui import *
#from PyQt4 import *
#from PyQt4.QtCore import *
#from PyQt4.QtGui import *
import sys
 
# In Qt, everything is a class.
# We can subclass stuff to do whatever we want - it seems a bit strange at first,
# but it keeps all related functionality in one place, which helps to keep you organised.
#
# We're subclassing 'QWidget' here. QWidget is the base class for all graphical elements in Qt.
# You can do all sorts of cool things like drawing your widget yourself, but we won't get into that.
#
# See also:
#   http://doc.trolltech.com/4.6/qwidget.html
class MyMainWindow(QWidget):
    def __init__(self):
        # first things first, we need to initialise the Qt parent, otherwise it won't work properly.
        #
        # A QWidget instance with no parent (None here) is a top level window.
        QWidget.__init__(self, None)
 
        # Now we start getting into building our interface. The first thing we need to learn about are layouts.
        # Layouts tell Qt where to put widgets, and how they fit with other widgets.
        # Unlike Gtk+, Qt layouts are *not* widgets - important difference to keep in mind.
        #
        # There are many types of layouts (from the complex, like QGridLayout) 
        # to the simple, like what we're using here.
        # See also:
        #   http://doc.trolltech.com/4.6/qlayout.html
        #   http://doc.trolltech.com/4.6/qvboxlayout.html
        vbox = QVBoxLayout()
 
        # Now let's create a button that can be pushed, and add it to our layout.
        #   http://doc.trolltech.com/4.6/qpushbutton.html
        b = QPushButton("Push me!")
        vbox.addWidget(b)
 
        # Let's make something happen when the button is pushed!
        self.connect(b, SIGNAL("clicked()"), self.buttonPushed)
 
        # Set the layout on the window: this means that our button will actually be displayed.
        self.setLayout(vbox)
 
    def buttonPushed(self):
        # Let's display a pretty dialog for fun.
        # Note that QDialog is themed to look very pretty in Maemo, think of e.g. the display of online IM accounts.
        # See also:
        #   http://doc.trolltech.com/4.6/qdialog.html
        d = QDialog(self)
 
        # Create another vertical layout, with a push button and a label, simple.
        vbox = QVBoxLayout()
 
        # First, the label:
        # QLabel is a simple class to display text (though it can of course do other cool things if you make it)
        #   http://doc.trolltech.com/4.6/qlabel.html
        l = QLabel("Hi there. You clicked a button!")
        vbox.addWidget(l)
 
        # Now the button.
        b = QPushButton("Close window")
 
        # Note that you can redirect signals and slots in a very cool way.
        # This redirects the button click action to close the window :)
        self.connect(b, SIGNAL("clicked()"), d.close)
 
        # Add the button to the box
        vbox.addWidget(b)
 
        # Display our layout
        d.setLayout(vbox)
 
        # Show the window!
        d.show()
 
if __name__ == '__main__':
    # QApplication controls things relating to a Qt application, like the main loop.
    # You should always instantiate it before using any QtGui related stuff.
    # See also:
    #   http://doc.trolltech.com/4.6/qapplication.html
    app = QApplication(sys.argv)
 
    # Create an instance (calling __init__, too, of course) of our window subclassing QWidget
    w = MyMainWindow()
 
    # Show our window
    w.show()
 
    # Main event loop of Qt. This won't return until the program exits.
    app.exec_()
    sys.exit()

Labels: , ,