Advanced widgets
It is with the advanced widgets that the
real fun starts. PyQt has a range of really powerful widgets
that allows you to build any kind of modern application you
desire.
You will notice that many advanced Qt
widgets are formed from the combination of a manager widget
class and an item class. This holds for
QCanvas with
QCanvasItem, for
QListView with
QListViewItem and for many others.
QSimpleRichText, QTextView and QTextBrowser
These classes implement rich text
viewers. They use html text and stylesheets to present data to
a user. QTextView is limited to one
page of text, while QTextBrowser
includes hyperlink navigation. The class
QStyleSheet is used to determine the
graphical rendering of the contents of
QTextView and
QTextBrowser.
QSimpleRichText is more like a label in
use, and is intended for smaller texts. Indeed, if you stuff a
QLabel with rich text, it will get
displayed using QSimpleRichText. These
classes do not provide a complete web-browser rendering engine
— that would be too much for a mere toolkit, but the
rendering is quite good.
QTextEdit
Available only in Qt3, not in Qt2,
QTextEdit is a rich text editing
widget. This is a very powerful class, almost a complete
wordprocessor in its own right - except that it doesn't have a
notion of the concept of ‘page'. The KDE Office wordprocessor,
KWord is built around it.
QTextEdit can display images, text
in fancy fonts across the whole Unicode range, tables and
lists. Internally, QTextEdit uses the
same subset of HTML that QTextView and
friends use. If your text is saved in a different file format,
you will first have to convert it to HTML, and that makes
QTextEdit difficult to use for purposes
such as a programmers editor, but has everything needed to create a rich
text input pane for an email client, for instance. (Not that I
condone sending html-formatted email!)
QListView and QListViewItem
This is possibly the most overworked PyQt class — it
seems to be used in almost every application.
QListView doubles as a listview and a
treeview. People coming from a Visual Basic background will
be delighted with the ease of use of this treeview. Adding
an item in a tree is a simple matter of creating a
QListViewItem with another
QListViewItem for a parent.
Example 10-11. tree.py - building a tree
#
# tree.py - a simple tree with QListView
#
import sys
from qt import *
class MainWindow(QMainWindow):
def __init__(self, *args):
apply(QMainWindow.__init__, (self,) + args)
self.tree = QListView(self)
self.setCentralWidget(self.tree)
self.tree.addColumn("item")
self.tree.setRootIsDecorated(1)
self.items=[]
self.items.append(QListViewItem(self.tree, "testself1"))
self.items.append(QListViewItem(self.items[-1], "child 1"))
self.items.append(QListViewItem(self.items[-2], "child 2"))
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)
Note that inserting items in an unsorted
QListView inserts the items at the top
of the listview. Thus, if you insert items A,
B and C, in that order, the order in the listview will be
C, B, A. Try adding the following line in the constructor,
before the listviewitems are created:
self.tree.setSorting(1,-1)
If you want your latest item to be the last in the branch,
then you will have to give the item it comes after as a second
argument— this can make for some quite irksome
bookkeeping. (Remember our little XML parser plus treeview in
the Section called A parser-formatter using signals and slots in Chapter 7? Well, this is the cause
of one nasty bug in that code! In that treeview, all items are
sorted within their node, and thus do not represent the
structure of the XML document.)
QIconView and QIconViewItem
If you are familiar with the Listview control that's
available on Windows, you might be somewhat surprised to learn
that Qt's listview doesn't include an icon view mode. There is
a separate icon view class QIconView
that provides all the functionality you might expect, except
for the easy switching between listview mode and iconview
mode. You will need to use two widgets in a widget-stack
(QWidgetStack) for that.
QSplitter
QSplitter is used to separate two
gui items that can take a variable amount of space. The user
can drag the splitter to give more room to one of those
items. Splitters can be horizontal or vertical, and you can
use splitters within splitters.
QCanvas, QCanvasView and QCanvasItems
This is a very powerful combination.
Canvases are typically used in graphics applications, games or
applications where a complex layout of text is required.
QCanvasView is the real widget that
includes scrollbars and can react to mouse presses or keyboard
interaction. A QCanvasView can show
(part of) a QCanvas, but a
QCanvas can be shown on more than one
QCanvasView. You can place
QCanvasItems on a
QCanvas. These items can represent
simple geometric forms, chunks of text or sprites (sprites are
independently moving, animated pictures). The following
classes implement QCanvasItem:
QCanvasSprite
QCanvasText
QCanvasPolygonalItem
QCanvasEllipse
QCanvasLine
QCanvasPolygon
QCanvasRectangle
From Qt 3, there is also
QCanvasSpline, which can be used to
draw bezier curves. Note that you cannot subclass
QCanvasItem — this is explicitly
forbidden in the Qt documentation: you will have to select a
more specialized subclass of
QCanvasItem.
Canvas items can move independently from each other, and
can be rendered on top of other items, or below others (by
clipping the obscured part). The PyQt canvas is completely
double-buffered and thus gives a very smooth
performance.
the Section called QCanvas in Chapter 21 shows a practical use for a
QCanvas.
QTable, QTableItem and QTableView (or
QGridView)
QTable and
QTableView are completely different
classes, but they should be discussed together, since both
implement a way for a developer to present tabular
data.
QTableView is rather difficult to
use — it has a primitive, low-level interface and code
based on it tends to be buggy. There is a lot of flexibility
built into QTableView, but you cannot
add widgets to cells. It has been deprecated in Qt3, where you
can use the QGridView class instead.
QTable, by
contrast, is a very high-level spreadsheet-like control,
eminently suited for the presentation of database data.
QTableItems are the items that fill the
cells of a QTable, and are editable.
It's easy to have a combobox or line editor pop-up when the
user selects a certain cell. Windows users especially will
know about the vast amount of ‘grid controls' that can
be bought for Visual Basic or Visual C++ —
QTable is the Qt equivalent, only not
so bloated as most of those grids are.