千月星跡

アイをも求めて彷徨っている孤独なヒーロー

last_impressionID:Last_Impression
[修改头像]
7182次访问,排名12950(-4)好友0人,关注者0
Last_Impression的文章
原创 44 篇
翻译 3 篇
转载 68 篇
评论 0 篇
最近评论
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes
文章分类
收藏
    相册
    存档

    转载 (转)3.7多文档(Multiple Documents)

    新一篇: (转)3.8启动画面(Splash Screens)

    现在我们开始实现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对象,而并没用new来创建。在程序中止的时候,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::newFile()要改成这样:
    void MainWindow::newFile()
    {
        MainWindow *mainWin = new MainWindow;
        mainWin->show();
    }
    我们只是简单的创建一个新的MainWindow实例。奇怪的是我们没有保存新窗口的指针,这是因为Qt会为我们记录所有窗口的地址。
    在MainWindow::createActions()中,我们需要Close和Exit行为:
    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();
    }
    上面的代码用到了Qt的foreach(这将在第11章介绍)遍历所有程序窗口,类型为MainWindow的窗口全部调用updateRecentFilesActions()。选项ShowGrid和AutoRecalculate也要这样处理进行同步,确保同一个文件不会调用两次。
    一个主窗口只能处理一个文档的程序称为SDI(single document interface)程序。只有一个主窗口,在其内部区域能管理多个文档窗口的程序称之为MDI(Multiple document interface)程序。Qt能够在所有操作系统平台上支持SDI和MDI程序。

    发表于 @ 2008年05月06日 20:59:39|评论(loading...)|编辑

    旧一篇: (转)3.6保存设置(Storing Settings)

    评论:没有评论。

    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © Last_Impression