精通Qt4编程
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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()返回应用程序的顶级窗口部件列表。对于任何一个文本编辑器实例,都要更新它的最近打开文件列表。

现在,重新编译、运行应用程序。