PyQt-複数ドキュメントインターフェイス

典型的なGUIアプリケーションには複数のウィンドウがあります。 タブ付きウィジェットとスタック済みウィジェットを使用すると、そのようなウィンドウを一度に1つアクティブにできます。 ただし、多くの場合、このアプローチは他のウィンドウの表示が非表示になるため、役に立たない場合があります。

複数のウィンドウを同時に表示する1つの方法は、それらを独立したウィンドウとして作成することです。 これはSDI(シングルドキュメントインターフェイス)と呼ばれます。 各ウィンドウには独自のメニューシステム、ツールバーなどがあるため、これにはより多くのメモリリソースが必要です。

MDI(Multiple Document Interface)アプリケーションは、より少ないメモリリソースを消費します。 サブウィンドウは、相互に関連してメインコンテナ内に配置されます。 コンテナウィジェットは QMdiArea と呼ばれます。

QMdiAreaウィジェットは通常、QMainWondowオブジェクトの中心ウィジェットを占有します。 この領域の子ウィンドウは、QMdiSubWindowクラスのインスタンスです。 QWidgetをsubWindowオブジェクトの内部ウィジェットとして設定することができます。 MDIエリアのサブウィンドウは、カスケード形式またはタイル形式で配置できます。

次の表は、QMdiAreaクラスとQMdiSubWindowクラスの重要なメソッドを示しています-

Sr.No. Methods & Description
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 PyQt4.QtCore import *
from PyQt4.QtGui 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