3

Qt を使用している間、常に Qt クラスから新しいクラスを派生させ、新しいクラスのインスタンスを作成します。たとえば、QMainWindow クラスを使用するには、たとえば MW と呼ばれる QMainWindow から新しいクラスを派生させ、MW からインスタンスを作成します。

私の質問は、この状況で QMainWindow から基本クラスからインスタンスを作成しないのはなぜですか?

4

3 に答える 3

3

ええ、私は何年も Qt を使用してきましたが、これについて考えたことさえありませんでした。良い質問です。

サブクラス化せずに QMainWindow を使用できる場合は、どうぞ。しかし、基本 QMainWindow クラス自体の有用性はかなり制限されると思います。

通常、サブクラスには数百または数千行のコードがあり、メニューの作成、シグナルやスロットの接続などを行っています。サブクラスにない場合、このコードが論理的にどこに存在するかわかりません。

QMainWindow に純粋な仮想がある可能性もあるため、オーバーライドする必要があります。しかし、私は知りません、見たことはありません。

あなたの質問であると私が理解していることに答えてくれることを願っています。

于 2012-10-03T21:58:28.560 に答える
1

QWidget / QMainWindow をサブクラス化する必要はありませんが、新しいプロジェクトと新しい UI ファイルを作成するための QtCreator アシスタントがサブクラス化します。

理由は簡単です。

  1. よりクリーンなコードを適用します。このウィジェット/ウィンドウの動作は、クラスの外ではなく、1 つのクラスに配置します。したがって、ウィンドウのすべてのインスタンスは同じ動作をします。QWidget / QMainWindow を単純にインスタンス化し、(外部から作成する必要があるウィジェットのシグナルに接続することによって) 外部から動作を追加する場合、それらのインスタンスは異なる動作を持つ可能性がありますが、これは明らかにオブジェクト指向設計では理解できないものです。

  2. 子ウィジェットはメンバーとして追加できます。ご存知のように、クラスにメンバーを追加できるのは、クラスをサブクラス化した場合のみです。サブクラス化しないと、ウィジェット/メイン ウィンドウを使用してこれらのポインターをコードに格納する必要があり、結果として不適切なコードになります。子ウィジェットへのポインタは、QObject ツリーに配置され、内部で Qt によって管理されるため、必ずしも保存する必要はありません。ただし、シグナルへの接続、QLineEdit からのテキストなどの値の読み取りなどは、それらのウィジェットへのポインターがある場合にのみ可能です。

  3. イベントの処理にはサブクラス化が必要です [編集:イベントフィルターを使用して実現することもできます。コメントを参照してください]。これらはシグナルとしてではなく仮想メソッドとして実装されるためです。これには、仮想 を再実装することによって行われるカスタム ペインティングも含まれますpaintEvent。イベントの処理には、マウス クリックへの反応 (これ自体を処理するサブウィジェットのクリックを除く)、マウス ホイールの回転、キーの押下、最小化と最大化なども含まれます。シグナルスロット接続を使用して処理できるウィンドウでの唯一の「アクション」は、それを閉じてコンテキストメニューを要求すること (右クリック) です (有効にしている場合)。したがって、これら 2 つは必ずしもサブクラス化を必要としません。

優れたオブジェクト指向コードのコンテキストでより一般的に話すと、サブクラスを作成するときのルールは明らかに次のとおりです。

  • 同じ入力/属性で同じように動作する同じもののインスタンスがある場合、それは同じタイプである必要があります。

  • しかし、異なる入力/属性に依存するだけでなく、異なる動作をしたいインスタンスがあるとすぐに、それは別のタイプ (サブクラス) である必要があります

  • クラスの (既に定義されている) 動作を変更する (「上書きする」) か、メンバーを追加する必要があるとすぐに、別の型 (サブクラス) にする必要があります。

于 2012-10-04T00:04:28.090 に答える
0

「常に」サブクラスを作成する必要があると言うのは、危険に聞こえます。私はむしろ「できるときは合成し、必要なときは継承する」に従いたいと思います。

QWidget は、コンテナーとして機能できるいくつかのケースを除いて、それ自体は役に立たず空であり、実際に何かを行うために特化することを意図しています。

QMainWindow は、外部から中央のウィジェット、メニュー バーなどを追加することにより、サブクラス化せずに完全に使用できます。ツールバー ボタンやメニュー エントリなどの QAction をどこかに接続する必要があるため、メインウィンドウにはこれらのアクションに作用するスロットが含まれていることが多く、サブクラス化を示唆しています。さまざまな部分を接続する中心的な場所を用意したり、ダイアログを表示したりすることは、手に負えなければ、やや自然で問題ありません。つまり、メイン ウィンドウに、アクション トリガーを転送して単にダイアログを表示するよりもはるかに多くのロジックが含まれている場合は、そのロジックをメイン ウィンドウの外に移動することを検討する必要があります。

ただし、サブクラス化用に設計されていないウィジェットは他にも多数あり、正当な理由なしにデフォルトでそれらをサブクラス化しても意味がありません。QLineEdit、QPushButton (特別なボタンが必要な場合は QAbstractButton をサブクラス化)、QCheckBox などをサブクラス化する意味はほとんどありません。これらは、動作を変更するために再実装できるウィジェット固有の仮想メソッドを提供しないためです。仮想メソッドを再実装しない限り、ほとんどの場合、構成は目標を達成するためのより良い方法です。はい、イベント フィルタを登録するよりも fooEvent() を再実装する方が簡単な場合があります。そのような場合はそれを行いますが、QLineEdit が必要なときに「MyLineedit」を作成することは無意味であり、私にとって悪い習慣です。

于 2012-10-04T07:18:39.570 に答える