Pyqt 简明教程
PyQt - Multiple Document Interface
典型的 GUI 应用程序可能有多个窗口。标签式和小部件可随时激活一个这样的窗口。但是,很多时候此方法可能没有用,因为其他窗口的视图被隐藏了。
A typical GUI application may have multiple windows. Tabbed and stacked widgets allow to activate one such window at a time. However, many a times this approach may not be useful as view of other windows is hidden.
同时显示多个窗口的一种方法是将它们创建为独立窗口。这称为 SDI(单文档界面)。这需要更多的内存资源,因为每个窗口可能都有自己的菜单系统、工具栏等。
One way to display multiple windows simultaneously is to create them as independent windows. This is called as SDI (single Document Interface). This requires more memory resources as each window may have its own menu system, toolbar, etc.
MDI(多文档界面)应用程序消耗更少的内存资源。子窗口相对于彼此放置在主容器中。容器小部件称为 QMdiArea 。
MDI (Multiple Document Interface) applications consume lesser memory resources. The sub windows are laid down inside main container with relation to each other. The container widget is called QMdiArea.
QMdiArea 小部件通常占据 QMainWondow 对象的中央小部件。此区域中的子窗口是 QMdiSubWindow 类的实例。可以将任何 QWidget 设置为子窗口对象的内部小部件。MDI 区域中的子窗口可以以层叠或平铺方式排列。
QMdiArea widget generally occupies the central widget of QMainWondow object. Child windows in this area are instances of QMdiSubWindow class. It is possible to set any QWidget as the internal widget of subWindow object. Sub-windows in the MDI area can be arranged in cascaded or tile fashion.
下表列出了 QMdiArea 类和 QMdiSubWindow 类的重要方法 -
The following table lists important methods of QMdiArea class and QMdiSubWindow class −
Sr.No. |
Methods & Description |
1 |
addSubWindow() Adds a widget as a new subwindow in MDI area |
2 |
removeSubWindow() Removes a widget that is internal widget of a subwindow |
3 |
setActiveSubWindow() Activates a subwindow |
4 |
cascadeSubWindows() Arranges subwindows in MDiArea in a cascaded fashion |
5 |
tileSubWindows() Arranges subwindows in MDiArea in a tiled fashion |
6 |
closeActiveSubWindow() Closes the active subwindow |
7 |
subWindowList() Returns the list of subwindows in MDI Area |
8 |
setWidget() Sets a QWidget as an internal widget of a QMdiSubwindow instance |
QMdiArea 对象发出 subWindowActivated() 信号,而 QMdisubWindow 对象发出 windowStateChanged() 信号。
QMdiArea object emits subWindowActivated() signal whereas windowStateChanged() signal is emitted by QMdisubWindow object.
Example
在以下示例中,包含 QMainWindow 的顶级窗口有一个菜单和 MdiArea。
In the following example, top level window comprising of QMainWindow has a menu and 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() 函数。
Triggered() signal of the menu is connected to windowaction() function.
file.triggered[QAction].connect(self.windowaction)
菜单的新操作向 MDI 区域中添加子窗口,其标题有一个递增的数字。
The new action of menu adds a subwindow in MDI area with a title having an incremental number to it.
MainWindow.count = MainWindow.count+1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("subwindow"+str(MainWindow.count))
self.mdi.addSubWindow(sub)
sub.show()
菜单的级联和平铺按钮分别以级联和平铺方式排列当前显示的子窗口。
Cascaded and tiled buttons of the menu arrange currently displayed subwindows in cascaded and tiled fashion respectively.
完整代码如下所示:
The complete code is as follows −
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()
上述代码生成以下输出 -
The above code produces the following output −