4.7 多文档
到目前为止,已经实现了一个简单的文本编辑器。用户在某一时刻,只能阅读、编辑一个文档,极为不方便。下面,在前面的单文档文本编辑器的基础上,实现文本编辑器的多文档功能。
实现文本编辑器的多文档,可以有多种方法:
● 在一个应用程序中实例化多个主窗口,即当打开或新建文档的时候,文本编辑器应用程序新建一个主窗口,这个主窗口单独加载和编辑文档。这种情况下,多个主窗口属于同一个应用程序,当关闭所有主窗口的时候,文本编辑器应用程序也就结束了运行。我们称这种方法为多实例实现编辑器的多文档。
● 使用QWorkspace作为主窗口的中心部件,在QWorkspace中打开多个子窗口,每一个子窗口可以单独对文档进行加载和编辑。
● 使用QMdiArea作为主窗口的中心部件,由QMdiArea实现对多个文档子窗口的管理(与Qworkspace的使用有些类似)。
下面,使用第一种方法实现简单文本编辑器的多文档功能,对于窗口部件QWorkspace和QMdiArea的使用将在第5章“布局管理”中学习。
在简单文本编辑器的例子中,只有一种情况会出现多文档:当新建一个文档的时候。读者可以进一步完善,比如在打开一个文档的时候,实现多个文档显示。
多实例实现编辑器的多文档比较简单,在前面的基础上,只需要修改两个地方就可以了。
// chapter04/designmainwindow/src/mainwindow.cpp. void CMainWindow::doNew() { CMainWindow* mainWindow = new CMainWindow; mainWindow->setVisible(true); }
槽函数doNew()创建一个新的主窗口CMainWindow对象,并进行显示。
修改函数setCurrentFile(),内容如下。
// chapter04/designmainwindow/src/mainwindow.cpp. void CMainWindow::setCurrentFile(const QString& fileName) { curFile = QFileInfo(fileName).canonicalFilePath(); isUntitled = false; setWindowTitle(curFile + "[*]"); textEdit->document()->setModified(false); setWindowModified(false);; QSettings settings("709", "SDI example"); QStringList files = settings.value("recentFiles").toStringList(); files.removeAll(fileName); files.prepend(fileName); while (files.size() > MaxRecentFiles) files.removeLast(); settings.setValue("recentFiles", files); foreach (QWidget *widget, QApplication::topLevelWidgets()) { CMainWindow *mainWindow = qobject_cast<CMainWindow *>(widget); if (mainWindow) mainWindow->updateRecentFiles(); } }
setCurrentFile()函数与原来的实现不同的地方,是多了对所有文本编辑器实例中最近文件列表的修改。
函数QApplication::topLevelWidgets()返回应用程序的顶级窗口部件列表。对于任何一个文本编辑器实例,都要更新它的最近打开文件列表。
现在,重新编译、运行应用程序。