注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

创思通信官网:www.csgsm.com

创思通信-引领物联网新时代 520ic.taobao.com

 
 
 

日志

 
 
 
 

纠正你的Qt编程习惯:主窗体的创建问题  

2010-03-14 14:26:57|  分类: Linux 、windows |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

题记: 要知道,并不是只有初学者才会犯错。(shiroki的至理名言)

最近发现了一些有意思的问题,值得memo一下。

先来看段代码:

#include <QApplication>
#include <QWebView>
#include <QUrl>
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    QWebView* mw = new QWebView;
    mw->show();
    mw->load(QUrl("http://www.cuteqt.com"));
    return a.exec();
}大家看得出这段代码中的问题吗? (呵呵,不要告诉我是cuteqt不能访问哦~)

这段代码ms十分标准, 非常符合笔者平时写Qt程序书写main函数的习惯, 孰料想竟然是个错误的习惯,而且问题很严重哦。 给个提示:在程序退出时会aborted。

如果还没想出来是什么问题,嘿嘿,没关系,看了下面的答案你就明白了。

这段程序里QApplication实例创建在stack上,生命期是main的大括号内, 而mw则通过new创建在heap上, 在程序退出时才会被析构。 换句话说,mw的生存期长于application的生存期…..这可是Qt编程的大忌, 因为在Qt中所有的Paint Device都必须要在有QApplication实例的情况下创建和使用。 不过如果把这个程序写出来运行一下, 未必会出现我说的aborted的问题,  大多数代码类似的程序都能安全的运行(这也是为什么用了那么多年的Qt从来没有注意过这个问题, 并且养成了我错误的编程习惯。)。  这里的trick在于application退出时mw已经被关闭, mw中的所有Paint Device一般都不会被访问到了, 所以这个错误隐藏在很深的阴暗角落, 偷偷地嘲笑我们呢!

要想试验这个问题也很简单,把load的参数换成本地文件 test.html, 并把下面的内容写进test.html就能看到拉:

 


-----test.html-----
<form>
<select id="headertest">
<option>Item1</option>
<option>Item2</option>
<option>Item3</option>
</select>
</form>这个html里使用了下拉选单。 如果你运行程序并点开该选单,之后退出程序你就会看到Aborted错误提示,并打印出错误信息:“QWidget: Must construct a QApplication before a QPaintDevice”。

既然提出的问题,当然也要给出解决的方案。 有两种可行的方法避免该错误。 一个当然是纠正一下编程习惯,对mw不要用new的方式创建,改在stack上创建,如下代码:

#include <QApplication>
#include <QWebView>
#include <QUrl>
int main(int arg, char* argv[])
{
    QApplication a(argc, argv);
    QWebView mw;
    mw.show();
    mw.load(QUrl("http://www.cuteqt.com"));
    return a.exec();
}另外还可以用Qt提供的API解决此问题, 想办法让mw在application之前clean up, 那就是用WA_DeleteOnClose属性。 该属性标示窗体会在close时被析构, 这样就保证不会留存在application析构之后了, 是个很好的办法。

代码如下:

#include <QApplication>
#include <QWebView>
#include <QUrl>
int main(int arg, char* argv[])
{
    QApplication a(argc, argv);
    QWebView* mw = new QWebView;
    mw->show();
    mw->setAttribute(Qt::WA_DeleteOnClose);
    mw->load(QUrl("http://www.cuteqt.com"));
    return a.exec();
}发现问题和解决问题是件很有乐趣的事情,大家不要把时间都浪费在猜测上,要多动手多思考才能进步!

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mociml/archive/2010/01/07/5148419.aspx

  评论这张
 
阅读(1017)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018