PyQt - Interface de documents multiples

Une application GUI typique peut avoir plusieurs fenêtres. Les widgets à onglets et empilés permettent d'activer une de ces fenêtres à la fois. Cependant, cette approche peut souvent ne pas être utile car la vue des autres fenêtres est masquée.

Une façon d'afficher plusieurs fenêtres simultanément consiste à les créer en tant que fenêtres indépendantes. Cela s'appelle SDI (interface de document unique). Cela nécessite plus de ressources mémoire car chaque fenêtre peut avoir son propre système de menus, sa propre barre d'outils, etc.

Les applications MDI (Multiple Document Interface) consomment moins de ressources mémoire. Les sous-fenêtres sont disposées à l'intérieur du conteneur principal les unes par rapport aux autres. Le widget conteneur est appeléQMdiArea.

Le widget QMdiArea occupe généralement le widget central de l'objet QMainWondow. Les fenêtres enfants de cette zone sont des instances de la classe QMdiSubWindow. Il est possible de définir n'importe quel QWidget comme widget interne de l'objet subWindow. Les sous-fenêtres de la zone MDI peuvent être organisées en cascade ou en mosaïque.

Le tableau suivant répertorie les méthodes importantes de la classe QMdiArea et de la classe QMdiSubWindow -

N ° Sr. Méthodes et description
1

addSubWindow()

Ajoute un widget en tant que nouvelle sous-fenêtre dans la zone MDI

2

removeSubWindow()

Supprime un widget qui est un widget interne d'une sous-fenêtre

3

setActiveSubWindow()

Active une sous-fenêtre

4

cascadeSubWindows()

Réorganise les sous-fenêtres dans MDiArea en cascade

5

tileSubWindows()

Organise les sous-fenêtres dans MDiArea en mosaïque

6

closeActiveSubWindow()

Ferme la sous-fenêtre active

sept

subWindowList()

Renvoie la liste des sous-fenêtres dans la zone MDI

8

setWidget()

Définit un QWidget comme un widget interne d'une instance QMdiSubwindow

L'objet QMdiArea émet le signal subWindowActivated () tandis que le signal windowStateChanged () est émis par l'objet QMdisubWindow.

Exemple

Dans l'exemple suivant, la fenêtre de niveau supérieur comprenant QMainWindow a un menu et MdiArea.

self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")

file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")

Le signal déclenché () du menu est connecté à la fonction windowaction ().

file.triggered[QAction].connect(self.windowaction)

La nouvelle action de menu ajoute une sous-fenêtre dans la zone MDI avec un titre comportant un numéro incrémentiel.

MainWindow.count = MainWindow.count+1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("subwindow"+str(MainWindow.count))
self.mdi.addSubWindow(sub)
sub.show()

Les boutons en cascade et en mosaïque du menu organisent respectivement les sous-fenêtres actuellement affichées en cascade et en mosaïque.

Le code complet est le suivant -

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()

Le code ci-dessus produit la sortie suivante -