PyQt5 - 多文件介面



一個典型的 GUI 應用程式可能有多個視窗。選項卡式和堆疊式控制元件允許一次啟用一個視窗。但是,很多時候這種方法可能並不實用,因為其他視窗的檢視會被隱藏。

同時顯示多個視窗的一種方法是將它們建立為獨立的視窗。這稱為 SDI **(單文件介面)**。這需要更多的記憶體資源,因為每個視窗可能都有自己的菜單系統、工具欄等。

MDI **(多文件介面)** 應用程式消耗更少的記憶體資源。子視窗在主容器內相互關聯地佈局。容器控制元件稱為 **QMdiArea**。

QMdiArea 控制元件通常佔據 QMainWindow 物件的中心控制元件。此區域中的子視窗是 **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)

選單的新操作在 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()

執行以上程式碼,三個視窗將以層疊和平鋪的形式顯示:

Multiple Document Interface Output1

Multiple Document Interface Output2

Multiple Document Interface Output3
廣告