糾正你的Qt編程習慣:主表單的建立問題

來源:互聯網
上載者:User

題記: 要知道,並不是只有初學者才會犯錯。(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/blog"));    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/blog"));    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/blog"));    return a.exec();}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.