3-7 多文档(Multiple Documents)

现在我们开始实现Spreadsheet程序的main()函数:

include <QApplication>

include "mainwindow.h"

int main(int argc, char *argv[])

{

    QApplication app(argc, argv);

    MainWindow mainWin;

    mainWin.show();

    return app.exec();

}

这个main()函数和以前实现的稍有不同:我们在堆栈上创建了MainWindow实例。在程序中止的时候,MainWindow自动销毁。

使用以上的main()函数,Spreadsheet程序提供一个主窗口,一次只能处理一个文档。如果我们希望在同时处理多个文档,我们就要同时启动多个Spreadsheet程序。这对用户来说很不方便,他们更喜欢在一个应用程序实例中打开多个窗口,就如同一个web浏览器可以同时打开多个窗口一样。

为了处理多文档,我们需要对Spreadsheet进行一点修改。首先File菜单要进行修改:

  • File|New 创建一个带有空文档的新的主窗口,而不是重新使用已经存在的主窗口。
  • File|Close 关闭当前主窗口。
  • File|Exit 关闭所有窗口。

在原来的程序版本中没有Close菜单项,因为这个菜单项和Exit时一样。

新的main()函数变为这样:

int main(int argc, char *argv[])

{

    QApplication app(argc, argv);

    MainWindow *mainWin = new MainWindow;

    mainWin->show();

    return app.exec();

}

由于有了多个主窗口,我们需要用new创建MainWindow实例,这样当保存后就可以使用delete删除MainWindow实例。

槽函数MainWindow::newFile()要改成这样:

void MainWindow::newFile()

{

    MainWindow *mainWin = new MainWindow;

    mainWin->show();

}

我们只是简单的创建一个新的MainWindow实例。奇怪的是我们没有保存新窗口的指针,这是因为Qt会为我们记录所有窗口的地址。

MainWindow::createActions()中,我们需要CloseExit行为:

void MainWindow::createActions()

{

    ...

    closeAction = new QAction(tr("&Close"), this);

    closeAction->setShortcut(tr("Ctrl+W"));

    closeAction->setStatusTip(tr("Close this window"));

    connect(closeAction, SIGNAL(triggered()), this, SLOT(close()));

    exitAction = new QAction(tr("E&xit"), this);

    exitAction->setShortcut(tr("Ctrl+Q"));

    exitAction->setStatusTip(tr("Exit the application"));

    connect(exitAction, SIGNAL(triggered()),

            qApp, SLOT(closeAllWindows()));

    ...

}

函数QApplication::closeAllWindows()关闭所有应用程序的窗口,除非有些窗口拒绝了这个关闭事件。这个功能是很需要的。因为只要关闭一个窗口,MainWindow::closeEvent()就会调用,这样我们就不用担心有些文档没有存盘。

到现在,看起来我们的程序已经能够处理多文档窗口了。但是还有一个隐藏的问题:如果用户不停的创建关闭主窗口,那么机器最终会耗尽所有内存。因为我们在newFile()中不停的创建主窗口 但是却没有删除它。用户关闭一个窗口只是把它隐藏,窗口实例一致在内存中。在内存中不用的主窗口越来越多,这个问题就很严重了。

解决这个问题很简单,在构造函数中我们把窗口属性设置为Qt::WA_DeleteOnClose就可以了:

MainWindow::MainWindow()

{

    ...

    setAttribute(Qt::WA_DeleteOnClose);

    ...

}

这样Qt就在窗口关闭的同时销毁它。QWidgets有许多可以影响行为的属性,Qt::WA_DeleteOnClose只是其中的一个。

内存泄漏只是我们需要处理的问题之一。在我们的原来程序设计中,我们假定只有一个主窗口。如果创建了多个窗口,那么每一个窗口都已个最近打开的文档和自己的设置。很明显,最近打开的文档应该是对程序全局有效的。我们可以声明recentFiles为静态变量,这样在整个程序运行期间就只有一份拷贝。这样我们就需要在调用updateRecentFilesActions()函数时,所有的主窗口都要调用,代码实现如下:

foreach (QWidget *win, QApplication::topLevelWidgets()) {

    if (MainWindow *mainWin = qobject_cast<MainWindow *>(win))

        mainWin->updateRecentFileActions();

}

上面的代码用到了Qtforeach(这将在第11章介绍)遍历所有程序窗口,类型为MainWindow的窗口全部调用updateRecentFilesActions()。选项ShowGridAutoRecalculate也要这样处理进行同步,确保同一个文件不会调用两次。

一个主窗口只能处理一个文档的程序称为SDIsingle document interface)程序。能处理多个文档的程序称之为MDIMultiple document interface)程序。Qt能够在所有操作系统平台上支持SDIMDI程序。

 

 
qq超大汉字生成器,可以选择字由什么字或者字符组成,背景谢什么字或者字符。 你你你你你你你你你你你你你你你你你你你你你你你你你你 你你你你你你你你你你你你你你你你你你你你你你你你你你 你你你你你你你你你你你你你你你你你你你你你你你你你你 你你你你你你你你你你你你你你你你你你你你你你你你你你 你你你你你你你你你你你你爱你你你你你你你你你你你你你 你你你你你你你你爱爱爱你爱爱你爱你你你你你你你你你你 你你你你你爱爱爱爱爱爱你爱你你爱爱你你你你你你你你你 你你爱爱爱你爱爱你你你你爱你你你爱爱爱你你你你你你你 你你你你你你爱爱你你你你爱你你你你爱爱你你你你你你你 你你你你你你爱爱你你你你爱你你你你爱你你你你你你你你 你你你你你你爱爱你你你你爱你你你你爱爱爱你你你你你你 你你你你你你爱爱你你你你爱爱你你你你你你你你你你你你 你你你你你你爱爱你你你你爱爱你你你爱你你你你你你你你 你你你你你你爱爱你你你你爱爱你你爱爱爱你你你你你你你 你你你你你你爱爱爱爱爱你爱爱你爱爱爱你你你你你你你你 你你你你你爱爱爱爱你你你爱爱你爱爱你你你你你你你你你 你爱爱爱爱爱爱爱你你你你你爱爱爱你你你你你你你你你你 你你爱爱你你爱爱你你你你你爱爱你你你你你你你你你你你 你你你你你你爱爱你你你你爱爱爱你你你你爱你你你你你你 你你你你你你爱爱你你你爱爱你爱爱你你你爱你你你你你你 你你你你你你爱爱你爱爱爱你你你爱爱你你爱你你你你你你 效果好像看不出来呀,下载后就能看出来了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值