PyQt - Multiple Document Interface



Several windows are available in a simple GUI application. In this UI, there is the need for tabbed or stacked widgets that help activate only one window at a time, although sometimes it may not be effective because other windows might be hidden from view.

The display of multiple windows continuously creates an independent window. This is called SDI (Single Document Interface). This requires more memory resources as each window may have its own menu system, toolbar, etc.

MDI (Multiple Document Interface) applications consume lesser memory resources. The sub windows are laid down inside main container with relation to each other. The container widget is called QMdiArea.

QMdiArea widget generally occupies the central widget of QMainWondow object. Child windows in this area are instances of QMdiSubWindow class. It is possible to set any QWidget as the internal widget of subWindow object. Sub-windows in the MDI area can be arranged in cascaded or tile fashion.

Following are the list of important methods in QMdiArea class and QMdiSubWindow class −

Sr.No. Methods & Description
1

addSubWindow()

Adds a widget as a new subwindow in MDI area

2

removeSubWindow()

Removes a widget that is internal widget of a subwindow

3

setActiveSubWindow()

Activates a subwindow

4

cascadeSubWindows()

Arranges subwindows in MDiArea in a cascaded fashion

5

tileSubWindows()

Arranges subwindows in MDiArea in a tiled fashion

6

closeActiveSubWindow()

Closes the active subwindow

7

subWindowList()

Returns the list of subwindows in MDI Area

8

setWidget()

Sets a QWidget as an internal widget of a QMdiSubwindow instance

QMdiArea object emits subWindowActivated() signal whereas windowStateChanged() signal is emitted by QMdisubWindow object.

Example

In the following example, top level window comprising of QMainWindow has a menu and 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() signal of the menu is connected to windowaction() function.

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

The new action of menu adds a subwindow in MDI area with a title having an incremental number to it.

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

Cascaded and tiled buttons of the menu arrange currently displayed subwindows in cascaded and tiled fashion respectively.

Below is the complete code to understand the structure of multiple document interface −

import sys
from PyQt6.QtWidgets import QMainWindow, QApplication, 
QMdiArea, QMdiSubWindow, QTextEdit
from PyQt6.QtGui import QAction
class MainWindow(QMainWindow):
   count = 0

   def __init__(self):
      super().__init__()
      self.mdi = QMdiArea()
      self.setCentralWidget(self.mdi)
      bar = self.menuBar()

      file = bar.addMenu("File [Click Here!]")
      file.addAction("New")
      file.addAction("Cascade")
      file.addAction("Tiled")
      file.triggered[QAction].connect(self.windowaction)
      self.setWindowTitle("Multi Document Interface")

   def windowaction(self, q):
      print("Triggered")

      if q.text() == "New":
         MainWindow.count += 1
         sub = QMdiSubWindow()
         sub.setWidget(QTextEdit())
         sub.setWindowTitle(f"subwindow{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()

Output

The above code produces the following output −

mdiarea

Below is the stepwise screenshots to understand interface in a detail manner.

Opening a new interface − By clicking a new option, the user gets the new inteface of Qt.

Multiple Document Interface Output1

Selction of Cascade option − By clicking a Cascade option, the user can see multiple tabs of interfaces.

Multiple Document Interface Output2

Selection of Option − By clicking a Tiled option, the user can partition the interface and it interacts within a single output window.

Multiple Document Interface Output3
Advertisements