PyQt5 - Многодокументный интерфейс

Типичное приложение с графическим интерфейсом может иметь несколько окон. Виджеты с вкладками и стеком позволяют активировать одно такое окно за раз. Однако во многих случаях этот подход может оказаться бесполезным, поскольку вид других окон скрыт.

Один из способов одновременного отображения нескольких окон - создать их как независимые окна. Это называется SDI.(single Document Interface). Для этого требуется больше ресурсов памяти, поскольку каждое окно может иметь свою собственную систему меню, панель инструментов и т. Д.

MDI (Multiple Document Interface)приложения потребляют меньше ресурсов памяти. Вспомогательные окна располагаются внутри основного контейнера относительно друг друга. Виджет контейнера называетсяQMdiArea.

Виджет QMdiArea обычно занимает центральный виджет объекта QMainWondow. Дочерние окна в этой области являются экземплярамиQMdiSubWindowкласс. Можно установить любой QWidget как внутренний виджет объекта subWindow. Подокна в области MDI могут быть расположены каскадом или мозаикой.

В следующей таблице перечислены важные методы класса QMdiArea и класса QMdiSubWindow.

Sr.No. Методы и описание
1

addSubWindow()

Добавляет виджет как новое подокно в область MDI

2

removeSubWindow()

Удаляет виджет, который является внутренним виджетом подокна

3

setActiveSubWindow()

Активирует подокно

4

cascadeSubWindows()

Располагает подокна в MDiArea каскадно

5

tileSubWindows()

Располагает подокна в MDiArea мозаичным способом

6

closeActiveSubWindow()

Закрывает активное подокно

7

subWindowList()

Возвращает список подокон в области MDI.

8

setWidget()

Устанавливает QWidget как внутренний виджет экземпляра QMdiSubwindow

Объект QMdiArea испускает сигнал subWindowActivated (), тогда как сигнал windowStateChanged () испускает объект QMdisubWindow.

пример

В следующем примере окно верхнего уровня, состоящее из QMainWindow, имеет меню и MdiArea.

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

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

Сигнал Triggered () меню связан с функцией windowaction ().

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

Новое действие меню добавляет подокно в область MDI с заголовком, к которому добавляется порядковый номер.

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

Каскадные и мозаичные кнопки меню упорядочивают отображаемые в данный момент подокна каскадно и мозаично соответственно.

Полный код выглядит следующим образом -

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

Выполните приведенный выше код и три окна в каскадной и мозаичной формации -