4

バックストーリー:

コードの一部をレビューしてもらいQMessageBox、エラーを表示するためのローカルを作成し、それをヒープに割り当てました。

if (getAutopilotList.error() == 0) {
    QMessageBox* error = new QMessageBox(0);
    error->setDetailedText(getAutopilotList.errorString());
    error->setText("something");
    error->setWindowTitle(tr("Error!"));
    error->show();
    return;
}

開発者は次のように述べています。

このポインターはリークします。親を設定せず、決して削除しません。ここでもポインタは必要ありません。親は 0 を使用せず、Core::ICore::mainWindow() を使用します。

次のように考えたので、私は混乱しました。

  1. QWidgets はヒープでのみ機能しました
  2. delete error;メッセージボックスが閉じられたときにポインターが自動的に表示されること。

QMessageBox をスタックに置いてみましたが、表示されませんでした。


質問:

  1. この QMessageBox をスタックに置いて動作させることはできますか?
  2. deleteQMessageBox ポインターを明示的に指定する必要がありますか?
  3. この場合、親を 0 を超える値に設定することが重要なのはなぜですか?
4

3 に答える 3

4

QMessageBox をスタックに置いてみましたが、表示されませんでした。

スレッドが範囲外になるとすぐに破棄されるためです。QMessageBox::exec()ブロックモードで実行するには、を使用する必要がありました。

于 2015-05-30T22:22:36.370 に答える
4

原則として、スタック上に QWidget オブジェクトを作成できます。ここでは、 の呼び出しがerror->show()メッセージ ボックスをすぐに表示しないため、機能しません。メインのイベント ループに戻ったときに表示をスケジュールするだけで、その時点でオブジェクトが破棄されます。そのため、deleteing theQMessageBoxも機能しません。親を設定すると、親自体が破棄されたときに、オブジェクトの破棄の責任が親に与えられます。これは良い考えです。

ただし、何をしたいのか理解できれば、ユーザーが [OK] ボタンをクリックするのを待ってからreturn. その場合は、QMessageBox::warningQMessageBoxなどの静的関数を使用することをお勧めします。

永続的なメッセージ ボックスが必要な場合、コードは問題ありませんが、次の呼び出しを追加する必要があります。

error->setAttribute(Qt::WA_DeleteOnClose);

これにより、対応するウィンドウが閉じられたときに削除がトリガーされます。

于 2015-05-30T22:22:59.403 に答える
3

スタック上の QWidget は機能しますが、スコープを離れるとスタック上のオブジェクトが削除されるため、ほとんどの場合実用的ではありません。

(多数の) Qt の例を見てみると、次のパターンが見つかります。

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);   
    MainWindow window; //inherits from QWidget, created on stack
    window.show();    
    return app.exec();
}

1)「QWidget on stack」という質問について-それが機能し、公式であることを証明する必要があります。しかし、これと QDialog::exec は、スタック上の QWidgets の唯一の使用例です。

2) 害はありません。コーディング ルールで new ごとに delete を呼び出す必要がある場合は、実行してください。それ以外の場合は、Qt::WA_DeleteOnClose を適切に設定し、閉じるときに削除できるようにします。

3) 親 0 について: 親を持つポインタへの参照を失うと安全です。親が削除されると、すべての子が自動的に削除されます (それらも忘れられている可能性があります)。そのため、長時間実行されるアプリケーションの場合、「メモリ リーク」は一時的なものにすぎません。parent =0 を使用すると、C++ の意味でのリークは発生しません。これにより、メモリ チェッカーがそのようなリークを検出できなくなります。ポインターは、いくつかの QObject ツリー トラバース関数を使用して引き続きアクセスできます。

于 2015-05-30T22:45:03.733 に答える