PyQt5 - 多文档界面


典型的 GUI 应用程序可能有多个窗口。选项卡式和堆叠式小部件允许一次激活一个这样的窗口。然而,很多时候这种方法可能没有用,因为其他窗口的视图被隐藏了。

同时显示多个窗口的一种方法是将它们创建为独立的窗口。这称为 SDI (单文档接口)。这需要更多的内存资源,因为每个窗口可能有自己的菜单系统、工具栏等。

MDI (多文档界面)应用程序消耗更少的内存资源。子窗口相对于彼此放置在主容器内。容器小部件称为QMdiArea

QMdiArea小部件通常占据QMainWondow对象的中央小部件。该区域中的子窗口是QMdiSubWindow类的实例。可以将任何 QWidget 设置为 subWindow 对象的内部小部件。MDI 区域中的子窗口可以按级联或平铺方式排列。

下表列出了 QMdiArea 类和 QMdiSubWindow 类的重要方法 -

先生。 方法与说明
1

添加子窗口()

在 MDI 区域中添加一个小部件作为新的子窗口

2

移除子窗口()

删除属于子窗口内部小部件的小部件

3

设置活动子窗口()

激活子窗口

4

级联子窗口()

以级联方式排列 MDiArea 中的子窗口

5

瓦片子窗口()

以平铺方式排列 MDiArea 中的子窗口

6

关闭活动子窗口()

关闭活动子窗口

7

子窗口列表()

返回MDI区域中的子窗口列表

8

设置小部件()

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

运行上面的代码和三个层叠和平铺的窗口 -

多文档接口输出1

多文档接口输出2

多文档接口输出3