PyQt5 - interfejs wielu dokumentów
Typowa aplikacja GUI może mieć wiele okien. Widżety na kartach i w stosach pozwalają na aktywację jednego takiego okna na raz. Jednak często takie podejście może nie być przydatne, ponieważ widok innych okien jest ukryty.
Jednym ze sposobów jednoczesnego wyświetlania wielu okien jest utworzenie ich jako niezależnych okien. Nazywa się to SDI(single Document Interface). Wymaga to więcej zasobów pamięci, ponieważ każde okno może mieć własny system menu, pasek narzędzi itp.
MDI (Multiple Document Interface)aplikacje zużywają mniej zasobów pamięci. Okna podrzędne są ułożone w głównym kontenerze względem siebie. Zostaje wywołany widget konteneraQMdiArea.
Widget QMdiArea zwykle zajmuje centralny widget obiektu QMainWondow. Okna potomne w tym obszarze są przykładamiQMdiSubWindowklasa. Możliwe jest ustawienie dowolnego QWidget jako wewnętrznego widgetu obiektu subWindow. Okna podrzędne w obszarze MDI można układać kaskadowo lub kafelkami.
Poniższa tabela zawiera listę ważnych metod klasy QMdiArea i klasy QMdiSubWindow -
Sr.No. | Metody i opis |
---|---|
1 | addSubWindow() Dodaje widget jako nowe podokno w obszarze MDI |
2 | removeSubWindow() Usuwa widżet, który jest wewnętrznym widżetem podokna |
3 | setActiveSubWindow() Aktywuje podokno |
4 | cascadeSubWindows() Układa podokna w MDiArea w sposób kaskadowy |
5 | tileSubWindows() Układa podokna w MDiArea w sposób kafelkowy |
6 | closeActiveSubWindow() Zamyka aktywne podokno |
7 | subWindowList() Zwraca listę okien podrzędnych w obszarze MDI |
8 | setWidget() Ustawia QWidget jako wewnętrzny widget instancji QMdiSubwindow |
Obiekt QMdiArea emituje sygnał subWindowActivated (), natomiast sygnał windowStateChanged () jest emitowany przez obiekt QMdisubWindow.
Przykład
W poniższym przykładzie okno najwyższego poziomu zawierające QMainWindow ma menu i MdiArea.
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")
file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")
Sygnał Triggered () menu jest połączony z funkcją windowaction ().
file.triggered[QAction].connect(self.windowaction)
Nowa akcja menu dodaje okienko podrzędne w obszarze MDI z tytułem posiadającym kolejny numer.
MainWindow.count = MainWindow.count+1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("subwindow"+str(MainWindow.count))
self.mdi.addSubWindow(sub)
sub.show()
Przyciski menu ułożone kaskadowo i sąsiadująco porządkują aktualnie wyświetlane podokna odpowiednio kaskadowo i kafelkowo.
Kompletny kod wygląda następująco -
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets 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()
Uruchom powyższy kod i trzy okna w układzie kaskadowym i kafelkowym -