5.5 多文档区部件QMdiArea
多文档区部件QMdiArea提供了一个管理/显示多文档界面的区域。它通常作为应用程序多文档界面主窗口的中心部件,实现对子窗口的管理、绘制和排布。同QWorkSpace不同的是,QMdiArea具有独特的多文档子窗口类QMdiSubWindow,它在多文档区部件内表现为一个顶层窗口,可以关闭、最小化和最大化,具有独立的窗口标题。QMdiSubWindow具有自己的布局管理器,该布局管理器管理窗口标题栏和放置窗口部件的中心区域。多文档子窗口QMdiSubWindow和多文档区部件QMdiArea共同实现应用程序的多文档功能。通常通过调用函数QMdiArea::addSubWindow()为一个多文档部件添加一个多文档子窗口,并返回该多文档子窗口的指针。
下面修改上一小节中多文档功能的主窗口定义文件和实现文件中的构造函数和槽函数doNew(),实现用户的“新建”操作。对于其他的功能,QMdiArea和QWorkSpace的实现是大同小异的,有兴趣的读者可以试着实现一下。
主窗口类CMainWindow的定义文件mainwindow.h部分如下。
…… class QMdiArea; class CMDITextEdit; class CMainWindow : public QMainWindow, public Ui::MainWindow { Q_OBJECT public: CMainWindow(QWidget* = 0); private: QDockWidget* dockWidget; QLabel* label1; QLabel* label2; enum{MaxRecentFiles = 9}; QAction* recentFileActs[MaxRecentFiles]; QAction* separatorAct; QMdiArea* mdiArea; …… };
在此,将与QWorkSpace相关的地方全部改为对QMdiArea的使用。
主窗口类CMainWindow的构造函数如下。
CMainWindow::CMainWindow(QWidget* parent) : QMainWindow(parent) { setupUi(this); mdiArea = new QMdiArea; setCentralWidget(mdiArea); connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow *)), this, SLOT(updateMenu())); iniDockWidget(); iniStatusBar(); iniConnect(); updateRecentFiles(); updateMenu(); showMaximized(); showCount(0); }
创建一个QMdiArea对象,并设置为主窗口的中心部件。关联信号QMdiArea::subWindowActivated()和槽函数CMainWindow::updateMenu(),当子窗口活动状态切换时更新菜单的状态。
void CMainWindow::doNew() { static int sequenceNum = 1; CMDITextEdit* textEdit = createMDITextEdit(true, tr("untitled%1").arg(sequenceNum++)); QMdiSubWindow* subWindow = mdiArea->addSubWindow(textEdit); subWindow->show(); }
当用户需要新建文档时,首先创建多文档文本编辑框CMDITextEdit对象textEdit,然后为多文档区部件添加多文档子窗口,并将刚创建的CMDITextEdit对象textEdit传递给QMdiArea::addSubWindow()函数,该函数将会把textEdit对象设置为多文档子窗口的中心区域的窗口部件。
多文档区部件QMdiArea实现的多文档应用程序与工作空间部件QWorkSpace的实现的多文档应用程序,界面上几乎完全相同,如图5-20所示。
图5-20 QMdiArea多文档应用程序界面
注意,在关闭多文档子窗口时,不会执行CMDITextEdit::closeEvent()函数。这是因为当多文档子窗口被关闭时,该当多文档子窗口自动被销毁了(所有子窗口部件也被销毁),并不会触发子窗口部件CMDITextEdit的关闭事件。如果要完成多文档子窗口关闭时保存文档的功能,一个办法是截获多文档子窗口的关闭事件(相关知识见第12章“事件处理”)。