PyQt5 – 多文档界面
一个典型的GUI应用程序可能有多个窗口。标签式和堆叠式部件允许一次激活一个这样的窗口。然而,很多时候,这种方法可能没有用,因为其他窗口的视图被隐藏了。
同时显示多个窗口的一种方法是将它们创建为独立的窗口。这被称为SDI(单一文档界面)。这需要更多的内存资源,因为每个窗口可能有自己的菜单系统、工具栏等。
MDI(多文档接口)应用程序消耗的内存资源较少。子窗口被放置在主容器内,相互之间有关系。容器小部件被称为QMdiArea。
QMdiArea小组件通常占据QMainWondow对象的中央小组件。这个区域的子窗口是QMdiSubWindow类的实例。它可以设置任何QWidget作为子窗口对象的内部部件。MDI区域中的子窗口可以以层叠或平铺的方式排列。
下表列出了QMdiArea类和QMdiSubWindow类的重要方法。
Sr.No. | 方法和描述 |
---|---|
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()
运行上述代码,三个窗口以层叠式和瓦片式形成 –