あなたのQtプログラミングの習慣を正します:メインフォームの作成の問題


メモ: 初心者だけが間違いを犯すわけではないことを知っておく必要があります.(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の生存期間はアプリケーションの生存期間より長い......これはQtプログラミングのタブーであり、QtのすべてのPaintデバイスはQAPplicationインスタンスがある場合に作成され、使用されなければならないからである.しかし、このプログラムを書き出して実行すると、私が言ったabortedの問題が発生するとは限らない. ほとんどのコードの似たようなプログラムは安全に実行できます(これもなぜ何年もQtを使ってこの問題に注意したことがなく、私の誤ったプログラミング習慣を身につけたのかです). ここのtrickはアプリケーションが終了した時に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 QPINTDevice」というエラーメッセージが印刷されます.
提起された問題である以上、解決策も当然与えなければならない.このエラーを回避するには、2つの実行可能な方法があります.1つはもちろんプログラミングの習慣を直して、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をclean upさせる方法も考えられます.それはWA_DeleteOnCloseプロパティ.このプロパティは、フォームがclose時にプロファイルされることを示しており、アプリケーションプロファイルの後に残らないことを保証するのに良い方法です.
コードは次のとおりです.
#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();

}