PyQt - Schnittstelle für mehrere Dokumente
Eine typische GUI-Anwendung kann mehrere Fenster haben. Mit Registerkarten und gestapelten Widgets kann jeweils ein solches Fenster aktiviert werden. Oft ist dieser Ansatz jedoch nicht sinnvoll, da die Ansicht anderer Fenster ausgeblendet ist.
Eine Möglichkeit, mehrere Fenster gleichzeitig anzuzeigen, besteht darin, sie als unabhängige Fenster zu erstellen. Dies wird als SDI (Single Document Interface) bezeichnet. Dies erfordert mehr Speicherressourcen, da jedes Fenster möglicherweise über ein eigenes Menüsystem, eine eigene Symbolleiste usw. verfügt.
MDI-Anwendungen (Multiple Document Interface) verbrauchen weniger Speicher. Die Unterfenster sind im Verhältnis zueinander im Hauptcontainer angeordnet. Das Container-Widget wird aufgerufenQMdiArea.
Das QMdiArea-Widget belegt im Allgemeinen das zentrale Widget des QMainWondow-Objekts. Untergeordnete Fenster in diesem Bereich sind Instanzen der QMdiSubWindow-Klasse. Es ist möglich, jedes QWidget als internes Widget des SubWindow-Objekts festzulegen. Unterfenster im MDI-Bereich können kaskadiert oder gekachelt angeordnet werden.
In der folgenden Tabelle sind wichtige Methoden der QMdiArea-Klasse und der QMdiSubWindow-Klasse aufgeführt.
Sr.Nr. | Methoden & Beschreibung |
---|---|
1 |
addSubWindow() Fügt ein Widget als neues Unterfenster im MDI-Bereich hinzu |
2 |
removeSubWindow() Entfernt ein Widget, das ein internes Widget eines Unterfensters ist |
3 |
setActiveSubWindow() Aktiviert ein Unterfenster |
4 |
cascadeSubWindows() Ordnet Unterfenster in MDiArea kaskadiert an |
5 |
tileSubWindows() Ordnet Unterfenster in MDiArea gekachelt an |
6 |
closeActiveSubWindow() Schließt das aktive Unterfenster |
7 |
subWindowList() Gibt die Liste der Unterfenster im MDI-Bereich zurück |
8 |
setWidget() Legt ein QWidget als internes Widget einer QMdiSubwindow-Instanz fest |
Das QMdiArea-Objekt gibt das Signal subWindowActivated () aus, während das Signal windowStateChanged () vom QMdisubWindow-Objekt ausgegeben wird.
Beispiel
Im folgenden Beispiel verfügt das Fenster der obersten Ebene, das aus QMainWindow besteht, über ein Menü und MdiArea.
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")
file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")
Das Triggered () -Signal des Menüs ist mit der windowaction () -Funktion verbunden.
file.triggered[QAction].connect(self.windowaction)
Die neue Menüaktion fügt im MDI-Bereich ein Unterfenster mit einem Titel hinzu, der eine inkrementelle Nummer enthält.
MainWindow.count = MainWindow.count+1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("subwindow"+str(MainWindow.count))
self.mdi.addSubWindow(sub)
sub.show()
Kaskadierte und gekachelte Schaltflächen des Menüs ordnen die aktuell angezeigten Unterfenster kaskadiert bzw. gekachelt an.
Der vollständige Code lautet wie folgt:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MainWindow(QMainWindow):
count = 0
def __init__(self, parent = None):
super(MainWindow, self).__init__(parent)
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")
file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")
file.triggered[QAction].connect(self.windowaction)
self.setWindowTitle("MDI demo")
def windowaction(self, q):
print "triggered"
if q.text() == "New":
MainWindow.count = MainWindow.count+1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("subwindow"+str(MainWindow.count))
self.mdi.addSubWindow(sub)
sub.show()
if q.text() == "cascade":
self.mdi.cascadeSubWindows()
if q.text() == "Tiled":
self.mdi.tileSubWindows()
def main():
app = QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Der obige Code erzeugt die folgende Ausgabe -