17

GUI を書いているとき、私はよく次の問題に直面しました。モデルとコントローラーがあるとします。コントローラーには、モデルWのプロパティを表示するために使用されるウィジェットがあります。X

モデルはコントローラーの外部から変更される可能性があるため (同じモデルを使用する他のコントローラーが存在する可能性があるため、元に戻す操作など)、コントローラーはモデルの変更をリッスンします。コントローラーはウィジェットのイベントもリッスンし、それに応じWてプロパティを更新しますX

ここで、次のことが起こります。

  1. の値Wが変更されます
  2. イベントが生成され、コントローラーのハンドラーが呼び出されます
  3. コントローラーモデルの新しい値を設定しXます
  4. モデルが変更されたため、モデルはイベントを発行します
  5. コントローラモデルから変更イベントを受け取ります
  6. コントローラーは値を取得し、Xウィジェットに設定します
  7. 1に行きます。

そのための解決策がいくつかあります。

  1. モデルが更新されたときにフラグを設定するようにコントローラーを変更し、このフラグが設定されている場合はモデルからのイベントに反応しないようにします。
  2. コントローラーを一時的に切断します (または、モデルにしばらくイベントを送信しないように指示します)。
  3. ウィジェットからの更新を凍結する

以前は、オプション 1. を選択していました。これが最も簡単だからです。クラスがフラグで雑然とするという欠点がありますが、他の方法にも欠点があります。

記録のために、GTK+、Qt、SWT などのいくつかの GUI ツールキットでこの問題が発生したので、ツールキットに依存しない問題だと思います。

ベストプラクティスはありますか? それとも、私が使用しているアーキテクチャが単に間違っているのでしょうか?

@Shy: これは場合によっては解決策ですがX、コントローラーの外部から変更された場合 (たとえば、元に戻す/やり直しのコマンド パターンを使用する場合) は、値が変更され、W更新されるため、余分なイベントのラウンドが発生します。そしてイベントを発生させます。モデルへの別の (無駄な) 更新を防ぐために、ウィジェットによって生成されたイベントを飲み込む必要があります。
他のケースでは、モデルがより複雑で、複雑なツリー ビューなど、何が正確に変更されたかを簡単に確認することができない場合があります。

4

3 に答える 3

5

これに対処する標準的なQTの方法と、非常に便利なチュートリアルで提案されている方法は、新しい値が現在の値と異なる場合にのみ、コントローラーの値を変更することです。
これは、信号が次のセマンティクスを持つ方法です。valueChanged()

このチュートリアルを参照してください

于 2008-09-24T00:29:55.100 に答える
3

通常、ウィジェットの入力イベントに応答し、イベントを変更しないようにする必要があります。これにより、このタイプのループが発生しなくなります。

  1. ユーザーがウィジェットの入力を変更する
  2. ウィジェットは変更イベントを発行します(スクロール完了/クリックされた入力/マウスを離すなど)
  3. コントローラが応答し、モデルの変更に変換します
  4. モデルはイベントを発行します
  5. コントローラが応答し、ウィジェットの値を変更します
  6. 値変更イベントが発行されましたが、コントローラーによってリッスンされていません
于 2008-09-24T00:45:03.800 に答える
1

更新作業を示すフラグ。それらをBeginUpdateやEndUpdateなどのメソッドでラップできます。

于 2008-09-24T00:36:38.233 に答える