Tutorial ======== Introduction ------------ Qt is a highly complex and versatile toolkit, but this flexibility sometimes makes it difficult to formulate workflows. This short tutorial illustrates a suitable workflow for developing desktop applications with PySide and qte. Hello World ----------- All tutorials start with a "Hello World" example:: import qte label = qte.QLabel('Hello World!') qte.runApp(label, 'MyApp') And here is an explanation of each line. 1. `qte` is imported. All of PySide's `!QtCore` and `!QtGui` classes, can be accessed directly from this namespace, as well as the extra objects provided by `qte`. 2. A new `!QLabel` is created from the `qte` namespace. 3. The application is launched with the label as the main window and the application name as 'MyApp'. The most important part of this example is the `qte.runApp` function. This is essentially equivalent to:: qte.Application().setApplicationName('MyApp') qte.Application().setMainWindow(label) win.setWindowTitle('MyApp') win.show() qte.Application().exec_() sys.exit() Note that `qte.Application` is used instead of `!QApplication`. The `qte.Application` class provides a few extra features which make it more suitable to desktop applications, such as settings management. It is also a singleton which on its first initialisation calls ``QApplication([sys.argv])``. UIs and Resources ----------------- Qt allows for two ways of designing user interfaces; they can either be hard coded or created using Qt Designer. In practice, it is common for a combination of these methods to be used. When coding Qt in C++, the normal workflow consists of designing the UI and creating resources in Qt Designer, then compiling them into binary files which can be inserted into the executable. In python, code is seldom compiled to an executable at all, so compiling *ui* and *qrc* files becomes a rather annoying and tedious exercise. `qte` provides an alternative may of dealing with these. Resources can be compiled at runtime using `qte.loadResource`. The binary data created by this is identical to the output of *rcc*, but the function is implemented purely in python, with no dependency on *rcc* or *pyside-rcc* at all. If used with the *register* argument, it also registers the data with the resource system so that resources can be used immediately. PySide's `!QUiLoader` class can be used to create widgets at runtime from *ui* files. `qte` extends this with `qte.loadUi` and `qte.uiWrapper`. `qte.loadUi` does the same job as `!QUiLoader.load`, but first registers custom widgets and resources. `qte.uiWrapper` wraps the widget in another class and is especially useful for `!QMainWindows` which cannot be promoted in Qt Designer. The following example shows how to load and inherit from a `!QMainWindow` interface created in Qt Designer. The window has a single button called ``showDialog`` which, when clicked, loads and displays a dialog from another *ui* file with itself as the parent. The button icon is read from a resource file:: import qte class MainWindow(qte.UiWrapper('ui/mainwindow.ui'): def __init__(self): qte.loadResource('icons.qrc', register=True) self.showDialog.setIcon(':dialog.png') self.showDialog.clicked.connect(self.loadDialog) def loadDialog(self): dialog = qte.QUiLoader().load('ui/dialog.ui', self) dialog.show() Model/View Programming ---------------------- One of the main problems with Qt's model/view framework in a python environment is the assumption that data is stored, or only visible through a `!QAbstractItemModel`. In C++ this is an ideal structure for storing structured data, but in python lists and dicts provide more flexibility. `qte.DataModel` gives this flexibility by wrapping a `!QAbstractItemModel` interface around generic python structures. Currently it only supports tabular data (i.e. which can be displayed in a `!QTableView`), but in the future tree-like structures will be supported too. An `qte.DataView` class is inherited from `!QTableView` and has a few extra features and customised defaults. There are also several new delegates, all based on `qte.TypedDelegate` which supports more data types than the default `!QItemDelegate`.