Application classes
Most gui applications consist of a main
window embellished with toolbars, a menu bar, and a statusbar,
and have a hole in the middle. The hole in the middle can be
filled with a specialized widget, or it may be a sort of
desktop-in-a- desktop, with its own windows, and with
sub-windows that dock themselves to the sides of the main
window. Often, and application includes a few secondary windows,
dialogs and a number of small popup-windows that warn or inform
the user.
We have already worked with a few of these
components. There is QApplication, the
base of every PyQt application.
QApplication wants to receive the
command-line arguments to determine the look and feel of the
application, as shown in
the Section called As simple as they come in Chapter 6.
Then there's the main window — as
shown in the Section called A better Hello World in Chapter 6, you can have
an unlimited number of main windows, and not all those main
windows have to be of the same class, as long as they inherit
QMainWindow.
We have yet to add the frills to the main
window. PyQt makes it quite easy to do this. The best way of
adding menu options and toolbar buttons is to create a
QAction for each action.
QAction is a class that brings together
user interface information about a certain action the user can
undertake in your application.
For instance, if you're developing a network client
application, one of the actions could be the command to
log in. Associated with this command
is a short help text that appears as a tooltip, a longer
help text that might appear in the status bar, an icon that is
used in the toolbar, a short text for use in the menu, and an
accelerator key that is used from the keyboard. The log in
action can be enabled or disabled (when the network is down, for
instance). You do not want to distribute all this functionality
all over your application.
A QAction ties everything related to
an action together, and can be added to toolbars and menus.
When performed, a QAction emits an activated()
signal. The following is a simple example with an action, a menubar, a toolbar
and a statusbar:
Example 10-2. action.py - Using a QAction to group data associated with
user commands
#
# action.py
#
import sys
from qt import *
connectIcon=["16 14 5 1",
" c None",
". c black",
"X c gray50",
"o c red",
"O c yellow",
" ",
" . ",
" X .X ",
" XooX . ",
" Xoooo .X ",
" XooooooX ",
" XooooooX ",
" XoooooX. ",
" XooooX. ",
" XOXXXX. ",
" XOXX... ",
" XOXX ",
" XX ",
" X "
]
class MainWindow(QMainWindow):
def __init__(self, *args):
apply(QMainWindow.__init__, (self, ) + args)
self.setCaption("Network Client")
# Define action
self.action=QAction(self, "login")
self.action.setText("Log in")
self.action.setMenuText("&Login")
self.action.setToolTip("Login to the central server")
self.action.setWhatsThis("Logs in to the central server.")
self.action.setStatusTip("Log in to the central server.")
self.action.setAccel(Qt.CTRL + Qt.Key_L)
self.action.setIconSet(QIconSet(QPixmap(connectIcon)))
self.connect(self.action,
SIGNAL("activated()"),
self.slotAction)
# Statusbar
self.statusBar=QStatusBar(self)
# Define menu
self.menu=QPopupMenu()
self.action.addTo(self.menu)
self.menuBar().insertItem("&File", self.menu)
# Define toolbar
self.toolBar=QToolBar(self, 'Main')
self.action.addTo(self.toolBar)
# Set a central widget
self.editor=QMultiLineEdit(self)
self.setCentralWidget(self.editor)
def slotAction(self):
QMessageBox.information(self,
"Network Client",
"Connecting to server...")
def main(args):
app=QApplication(args)
win=MainWindow()
win.show()
app.connect(app, SIGNAL("lastWindowClosed()")
, app
, SLOT("quit()")
)
app.exec_loop()
if __name__=="__main__":
main(sys.argv)
When, in Chapter 24, we reach
the pinnacle of development of Kalam,
the extensible Unicode editor, you will have become
very familiar with
QAction.
Multiple document windows with QWorkspace
The MDI (multiple document interface) is
a paradigm made popular by Microsoft, in which one application
window contains several document windows. For certain classes
of application, such as programming editors, this is a very
comfortable paradigm, but most users tend to get very confused
when confronted with windows that don't show up in their
taskbar. In fact, a large percentage of users have trouble
when there is more than one window on their desktop.
However, the functionality is available,
and it might be useful for your
application. Let's take our high-powered graphics editor, from
the event1.py example, and give the user ten windows to
scribble in. All that is needed is it to add the
Painting to a
QWorkspace object, instead of setting
it as the central widget of the
MainWindow.
Realistically, you'll want to offer menu
options for selecting, tiling and cascading the windows.
QWorkSpace provides a
tile() and a
cascade() slot for these purposes, as
well as a windowList that returns a list
of all windows. While it is a bad idea to limit your users to
a small maximum number of documents, if you let them open
more, you should provide a separate window with a full list.
Having more than ten windows to select from in a menu makes
working difficult.
Example 10-3. fragment from mdi.py - ten little scribbling windows
...
class MainWindow(QMainWindow):
def __init__(self, *args):
apply(QMainWindow.__init__, (self,) + args)
self.setCaption("MDI Scribbler")
self.workspace=QWorkspace(self, "workspace")
self.winlist=[]
for i in range(10):
win=Painting(self.workspace)
win.resize(100,100)
win.setCaption("Window " + str(i))
self.winlist.append(win)
self.setCentralWidget(self.workspace)
...