Nothing like getting the feet wet: let's investigate the
structure of a PyQt application by putting together the minimal
set of components that can show something on screen, slowly
expanding it to show more features.
A tiny PyQt applications has the following elements:
an application object
a main window (which has a central widget), or
a main widget
This is the traditional ”Hello World” button
application, with as little code as possible:
We need to import the Python
sys package, because the
QApplication object wants to look
at the command-line arguments the script is started
with. For instance, starting the script with
python hello1.py -style=platinum
starts the script with the look and feel of Mac-OS 8.5,
by passing the “-style=platinum” option
through to the QApplication object.
One of the niceties of Qt is that
you have access to all supported widget styles on all
platforms. (Except for the Aqua style - that is only
available on OS X, because Apple doesn't want it to
spread to other platforms.)
Next, we have to import the qt
library. While it is possible to import only explicitly
the elements from the library we need, it's just as easy
and efficient to import the whole library. But we could
have said:
from qt import QApplication,
QPushButton
From version 3.x of PyQt, the
library has been split into several separate modules.
The Qt module still gets you all the
basic stuff, but more advanced functionality, such as
the canvas, is divided over separate modules,
qtcanvas for
QCanvas, for instance.
After importing the necessary
modules, we create a Qt application object. This object
handles the dispatching of events from the mouse and
keyboard to the various widgets of the application.
Never try to create more than one
QApplication object, not even if
you embed Python and PyQt in a C++ Qt application. In
that case, the C++ application should create the
QApplication object and pass a
reference to the embedded Python interpreter.
To keep things simple, we do not create a separate
window object, but rather simply a pushbutton, of the type
QPushButton. The first argument
to the creation of the
QPushButton is the text that is
shown on the button. Since this is the only widget of
the application, it doesn't have a parent. This is what
the None argument means —
there is no parent, and the
QPushButton is the root of the
application widget tree.
However, we still need to apprise
the QApplication object of that
fact — this is done by telling the
QApplication that our button is
the main widget:
app.setMainWidget(button)
Then we show()
the button to the world.
Until the application objects
starts the event loop, nothing will appear on screen.
The call app.exec_loop() does
return a value, but we can safely disregard it.
Note: Note that this is one of the few
instances where a method name differs between Python and C++:
the C++ method is called exec(), which is
a reserved word in Python. Except for a few cases like this,
reading the C++ documentation for Python use demands little
more than a simple mental substitution.
Experienced Pythoneers will also note
that the parameters in PyQt function calls are positional
— not by keyword. In the old Tkinter GUI toolkit most
function calls take the form:
b = Button(root, text=label, command=func)
where PyQt wants:
b = QPushButton(root, label, func)
Just something to be aware of: keyword
parameters can be added in any old order, but positional
parameters have to be in the right position.