4

QWidgets をプログラムで追加する場合、QWidgets を初期化する最良の方法 (場所) は何ですか?

私はそれを行う方法を考えることができます:

1) 定義ファイルにインスタンスを作成し、初期化子リストで初期化します。これは正しい方法のようですが、ウィンドウに追加する必要がある QWidget が増えるほど、ずさんになります。

class SomeWindow : QDialog{
...
private:
  QLabel label1;
  QLabel label2;
...
}

SomeWindow::SomeWindow(...) : QDialog(...),
 label('label1 text'), label('label2 text')
{
...
  layout.addWidget(&label1);
  layout.addWidget(&label2);
...
}

2) C# から来ている私はこれを好む傾向がありますが、メモリ リークが発生するようです...

SomeWindow::SomeWindow(...) : QDialog(...)
{
  QLabel* label1 = new QLabel('label1 text');
  QLabel* label2 = new QLabel('label2 text');
...
  layout.addWidget(label1);
  layout.addWidget(label2);
...
}

私が見逃しているこれを行うためのより良い方法はありますか?

初歩的な質問で申し訳ありません。

4

3 に答える 3

3

Qt は独自のシステムを使用して、親子 QObject 派生クラスを削除します。オブジェクトを削除すると、すべての子も削除されます。

最初のコードでは、(SomeWindow のデストラクタと QObject システムで) 2 つの破壊があり、このコードは違法です (Qt のみ; C++ 標準コードでは問題ありません)。

2 番目のコードでは、QObject システムによってラベルが削除されるため、メモリ リークは発生しません。オブジェクトにポインターを保持する必要はありません。

@ジャイロ

コンストラクターで親を設定することは、子をオブジェクトに追加する唯一の方法ではありません。具体的には、QLayout::addWidget オブジェクトの親を変更します (レイアウトが正しくオブジェクトの子である場合)。

@msgmaxim

注意してください、レイアウトはコンストラクターのローカル変数であってはなりません

于 2013-09-25T06:58:18.963 に答える
1

新しいウィジェットを初期化するには、2 つの方法が適しています。

最初のケースでは、オブジェクトとしてラベルがあります。したがって、 SomeWindow が破棄されると、それらも自動的に破棄されます。オブジェクトではなくウィジェットへのポインターがある場合は、ラベルをダイアログのデストラクタに削除する必要があります (削除できます)。

SomeWindow::~SomeWindow()
{
    delete label1;
    label2.deleteLater(); // A safer way to delete a widget. Thread-safe.
}

2 つ目のケースでは、ウィジェットをデストラクタに削除する方法がないため、メモリ リークが発生します。ただし、ラベルの親を定義すると、親も削除されると削除されます。QWidgetのドキュメントをご覧ください。

親が 0 の場合、新しいウィジェットはウィンドウになります。親が別のウィジェットの場合、このウィジェットは親内の子ウィンドウになります。親が削除されると、新しいウィジェットも削除されます。

さらに、オブジェクト コンストラクターが親 QWidget または QObject を要求するときはいつでも、親が削除されると Qt がオブジェクトを削除すると考えることができます。

私も初心者ですが、参考になれば幸いです。

于 2013-09-25T06:39:32.787 に答える