PyQt5 - 多文档界面

  • 简述

    一个典型的 GUI 应用程序可能有多个窗口。选项卡式和堆叠式小部件允许一次激活一个这样的窗口。然而,很多时候这种方法可能没有用,因为其他窗口的视图被隐藏了。
    同时显示多个窗口的一种方法是将它们创建为独立的窗口。这称为 SDI(single Document Interface). 这需要更多的内存资源,因为每个窗口可能有自己的菜单系统、工具栏等。
    计量吸入器(Multiple Document Interface)应用程序消耗更少的内存资源。子窗口相对于彼此放置在主容器内。容器小部件被称为QMdiArea.
    QMdiArea 小部件一般占据 QMainWondow 对象的中心小部件。此区域中的子窗口是QMdiSubWindow班级。可以将任何 QWidget 设置为 subWindow 对象的内部小部件。MDI 区域中的子窗口可以以级联或平铺方式排列。
    下表列出了 QMdiArea 类和 QMdiSubWindow 类的重要方法 -
    序号 方法和描述
    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)
    
    menu 的新动作在 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