Frames and manager¶
The basic building blocks of a qtaui based UI are frames, which are instances of QAUILeafFrame
(a QWidget really). The application must also hold an instance of QAUIManager
, which acts as a common ancestor and repository for frames. So the skeleton of a qtaui based application would be:
from PySide import QtGui
from qtaui import QAUIManager, QAUILeafFrame
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.manager = QAUIManager()
self.setCentralWidget(self.manager)
# Let's add a simple empty frame
self.manager.addFrame(QAUILeafFrame(self.manager, title='I am a frame'))
if __name__ == '__main__':
app = QtGui.QApplication([])
win = MainWindow()
win.show()
win.raise_()
app.exec_()
Which will look pretty uninteresting:
Frame position¶
the QAUIManager.addFrame()
method takes an optional position argument, which value must be one of the constants defined in the QAUIPos
class. The default value is QAUIPos.CENTER
, which means to add the frame as a new tab. Other values are:
QAUIPos.LEFT
- Add the frame as a new column in an horizontal splitter, to the left.
QAUIPos.RIGHT
- Add the frame as a new column in an horizontal splitter, to the right.
QAUIPos.TOP
- Add the frame as a new row in a vertical splitter, to the top.
QAUIPos.BOTTOM
- Add the frame as a new row in a vertical splitter, to the bottom.
QAUIPos.FLOATING
- Add the frame as a top-level widget.
The frame that will be replaced in the hierarchy by a splitter/tabbed interface is the one the QAUILeafFrame.addFrame()
method is called on. So we can already build a not so simple interface:
- Tab #1
- Vertical splitter with frames 1 and 2
- Tab #2
- Horizontal splitter with frames 3 and 4
With the following code:
from PySide import QtGui
from qtaui import QAUIManager, QAUILeafFrame, QAUIPos
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.manager = QAUIManager()
self.setCentralWidget(self.manager)
tab1 = self.manager.addFrame(QAUILeafFrame(self.manager, title='Frame #1'))
tab1.addFrame(QAUILeafFrame(self.manager, title='Frame #2'), QAUIPos.BOTTOM)
tab2 = self.manager.addFrame(QAUILeafFrame(self.manager, title='Frame #3'))
tab2.addFrame(QAUILeafFrame(self.manager, title='Frame #4'), QAUIPos.LEFT)
self.resize(600, 300)
if __name__ == '__main__':
app = QtGui.QApplication([])
win = MainWindow()
win.show()
win.raise_()
app.exec_()
Undocking a frame¶
Leaf frames and tabs have a title bar. The user can drag the frame from this titlebar in order to undock it, i.e. to make it into a top-level widget. The parent container of the undocked widget will be replaced by the appropriate one if this leads to it containing only one or zero frames; for instance a tabbed container will be replaced by a plain one, thus removing the tabs. Undocking the frame #4 in the previous example will lead to this:
When a frame is undocked, the frame itself emits a QAUILeafFrame.undocked()
signal and the manager emits a QAUIManager.frameUndocked()
signal. There are also QAUILeafFrame.docked()
and QAUIManager.frameDocked()
signals. See the Class reference for more information.
Note
Since Qt does not exit the main event loop as long as there are visible top-level widgets, a convenience method of the QAUIManager
class allows you to hide all undocked frames at once; this must typically be called on program termination, from your main window:
def closeEvent(self, event):
self.manager.shutdown()
event.accept()
Docking a frame¶
When the user is dragging an undocked frame around, the QAUIManager
goes into “drop” mode, which is a graphical representation of the UI hierarchy, with hints as to where the frame can be dropped in order to dock it:
Each part of the hierarchy has five drop targets, each mapping to one of the positions defined in QAUIPos
.