2008-09-24 7 views
17

GUIを書くとき、私は頻繁に次の問題を克服しています。モデルとコントローラがあるとします。コントローラにはモデルのXプロパティを表示するために使用されるウィジェットWがあります。GUIのイベントサイクルを中断する

コントローラーの外からモデルが変更される可能性があるため(同じモデルを使用する他のコントローラーがある場合や操作の取り消しなど)、コントローラーはモデルの変更を待ち受けます。コントローラはまた、ウィジェットWのイベントをリッスンし、それに応じてプロパティXを更新します。今

、次の処理が行われます

  1. Wにイベントが発生し
  2. 変更され、コントローラにおけるハンドラは新しい値を設定
  3. コントローラが起動されXモデル
  4. m odelは、コントローラコントローラXの値が取得
  5. モデルから変更イベントを受信
  6. 変更されているので、イベントを放出し、ウィジェット
  7. ジャンプ1
  8. に設定します

そのためのいくつかの可能なソリューションがあります。

  1. モデルが更新されたときにフラグを設定し、このフラグが設定されている場合はモデルからのイベントに反応しないようにコントローラを変更します。
  2. 外し、一時的にコントローラ(またはいくつかの時間のための任意のイベントを送信していないモデルを伝える)
  3. 過去にウィジェット

から更新をフリーズそれはだから、私は通常、オプション1のために行ってきました最も簡単なこと。それは、フラグでクラスを混乱させるという欠点がありますが、他のメソッドにも欠点があります。

私はGTK +、Qt、SWTなどのいくつかのGUIツールキットでこの問題を抱えていたので、かなりツールキットには依存しないと思います。

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

@Shy:場合によっては解決策ですが、コントローラの外側からXが変更された場合(たとえば、元に戻す/やり直しのコマンドパターンを使用する場合など)には余計なイベントが発生します。が変更された場合、Wが更新され、イベントが発生します。モデルに対する別の(役に立たない)更新を防ぐために、ウィジェットによって生成されたイベントは飲み込まなければならない。
場合によっては、モデルがより複雑になり、正確に何が変更されたかを簡単にチェックすることが実現できない可能性があります。複雑なツリービュー。

+0

MFCのリストボックスで常にこの問題が発生します。 –

答えて

3

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

  1. ユーザーが
  2. ウィジェットは、変更イベントを発するウィジェットに入力を変更する(など、行わ/入力します。クリック/マウスが去るスクロール)
  3. コントローラが応答するには、
  4. モデルがイベントを発するモデルの変化に変換しますコントローラが応答
  5. は、
  6. 値変更イベントが発せられたが、コントローラによって聴かない
  7. ウィジェットの値を変更
+0

提案していただきありがとうございます。残念ながら、これはGUIツールキットによっては必ずしも可能ではありません。 –

5

これを扱う標準のQT方法と、非常に便利なチュートリアルで提案されている方法は、新しい値が現在の値と異なる場合にのみコントローラの値を変更することです。
これは、信号がupdaing作業を示すためにvalueChanged()

see this tutorial

1

国旗の意味を持っている方法です。 BeginUpdateやEndUpdateのようなメソッドでラップすることができます。

+0

これは一般的な慣行ですか、あるいは教育的な推測を行っていますか? – Statement

+0

複数のViewアーキテクチャを持つドキュメントを持つMFC Windows開発で、フラグを使用してステータスを更新しています。もっと最近の.NETのWindows開発では、選択時の変更イベントがinit中に発生したかどうかを示すためにフラグを使用し、無視することができました。 – Leah