分析Qt编程习惯 主窗体创建问题

移动开发
分析Qt编程习惯 主窗体创建问题是本文介绍的内容,先来看内容。

本文介绍的是分析Qt编程习惯 主窗体创建问题,要知道,并不是只有初学者才会犯错。最近发现了一些有意思的问题,值得memo一下。

先来看段代码:

  1. #include <QApplication> 
  2. #include <QWebView> 
  3. #include <QUrl> 
  4. int main(int argc, char* argv[])  
  5. {  
  6.     QApplication a(argc, argv);  
  7.     QWebView* mw = new QWebView;  
  8.     mw->show();  
  9.     mw->load(QUrl("http://www.cuteqt.com/blog"));  
  10.     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就能看到拉:

  1. <form> 
  2. <select id="headertest"> 
  3. <option>Item1</option> 
  4. <option>Item2</option> 
  5. <option>Item3</option> 
  6. </select> 
  7. </form>  

这个html里使用了下拉选单。如果你运行程序并点开该选单,之后退出程序你就会看到Aborted错误提示,并打印出错误信息:“QWidget: Must construct a QApplication before a QPaintDevice”。

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

  1. #include <QApplication> 
  2. #include <QWebView> 
  3. #include <QUrl> 
  4. int main(int arg, char* argv[])  
  5. {  
  6.     QApplication a(argc, argv);  
  7.     QWebView mw;  
  8.     mw.show();  
  9.     mw.load(QUrl("http://www.cuteqt.com/blog"));  
  10.     return a.exec();  

另外还可以用Qt提供的API解决此问题,想办法让mw在application之前clean up,那就是用WA_DeleteOnClose属性。该属性标示窗体会在close时被析构,这样就保证不会留存在application析构之后了,是个很好的办法。

代码如下:

  1. #include <QApplication> 
  2. #include <QWebView> 
  3. #include <QUrl> 
  4. int main(int arg, char* argv[])  
  5. {  
  6.     QApplication a(argc, argv);  
  7.     QWebView* mw = new QWebView;  
  8.     mw->show();  
  9.     mw->setAttribute(Qt::WA_DeleteOnClose);  
  10.     mw->load(QUrl("http://www.cuteqt.com/blog"));  
  11.     return a.exec();  

发现问题和解决问题是件很有乐趣的事情,大家不要把时间都浪费在猜测上,要多动手多思考才能进步!

Qt Jambi也存在类似的问题,如果以程序启动的代码块去启动QApplication,在程序运行过程中,一些资源回收会报出Null指针错误,这些错误,通过debug,最终都会指向QWidget这个类。当把QApplication启动的执行程序移出main函数,问题迎刃而解。要多注意细节。

小结:分析Qt编程习惯 主窗体创建问题的内容介绍完了,希望本文对你有所帮助!更多内容请参考编辑推荐。

责任编辑:zhaolei 来源: 互联网
相关推荐

2011-06-23 15:10:39

Qt 窗体

2011-04-13 10:16:41

编程习惯

2011-03-29 12:41:49

编程

2011-06-20 16:38:33

Qt QWidget Qt4.5

2009-07-24 18:02:46

ASP.NET编程

2017-09-01 11:01:22

开发编程习惯

2014-03-06 09:43:54

代码编程习惯

2015-08-17 10:13:35

ios习惯高效

2011-06-28 09:39:31

Qt

2020-10-30 07:11:31

C 语言编程

2011-06-22 10:12:08

Qt 线程

2009-10-14 15:34:29

VB.NET窗体编程模

2020-04-22 10:35:07

编程学习技术

2015-08-20 10:50:33

iOS高效编程习惯

2011-06-22 09:40:32

QT 模板库 模板

2010-01-13 15:52:59

VB.NET浮动窗体

2009-10-14 15:20:21

VB.NET窗体指针

2011-06-10 12:44:09

2011-06-13 16:51:19

Qt Socket

2011-06-24 15:30:22

QT 皮肤 QSS
点赞
收藏

51CTO技术栈公众号