PyQt5 - Interface para vários documentos

Um aplicativo GUI típico pode ter várias janelas. Os widgets com guias e empilhados permitem ativar uma janela por vez. No entanto, muitas vezes essa abordagem pode não ser útil, pois a visualização de outras janelas está oculta.

Uma maneira de exibir várias janelas simultaneamente é criá-las como janelas independentes. Isso é chamado de SDI(single Document Interface). Isso requer mais recursos de memória, pois cada janela pode ter seu próprio sistema de menu, barra de ferramentas, etc.

MDI (Multiple Document Interface)os aplicativos consomem menos recursos de memória. As subjanelas são colocadas dentro do contêiner principal em relação umas às outras. O widget de contêiner é chamadoQMdiArea.

O widget QMdiArea geralmente ocupa o widget central do objeto QMainWondow. Janelas filhas nesta área são instâncias deQMdiSubWindowclasse. É possível definir qualquer QWidget como widget interno do objeto subWindow. As subjanelas na área MDI podem ser dispostas em cascata ou lado a lado.

A tabela a seguir lista métodos importantes da classe QMdiArea e da classe QMdiSubWindow -

Sr. Não. Métodos e Descrição
1

addSubWindow()

Adiciona um widget como uma nova subjanela na área MDI

2

removeSubWindow()

Remove um widget que é interno de uma subjanela

3

setActiveSubWindow()

Ativa uma subjanela

4

cascadeSubWindows()

Organiza subjanelas em MDiArea em cascata

5

tileSubWindows()

Organiza subjanelas em MDiArea em mosaico

6

closeActiveSubWindow()

Fecha a subjanela ativa

7

subWindowList()

Retorna a lista de subjanelas na Área MDI

8

setWidget()

Define um QWidget como um widget interno de uma instância QMdiSubwindow

O objeto QMdiArea emite o sinal subWindowActivated (), enquanto o sinal windowStateChanged () é emitido pelo objeto QMdisubWindow.

Exemplo

No exemplo a seguir, a janela de nível superior composta por QMainWindow tem um menu e MdiArea.

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

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

O sinal disparado () do menu está conectado à função windowaction ().

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

A nova ação do menu adiciona uma subjanela na área MDI com um título que possui um número incremental.

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

Os botões em cascata e lado a lado do menu organizam as subjanelas atualmente exibidas em cascata e lado a lado, respectivamente.

O código completo é o seguinte -

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

Execute o código acima e três janelas em formação cascased e lado a lado -