0

WT で興味深い問題に遭遇し、解決しましたが、私のソリューションが問題を解決した理由がわかりません。私はウィジェットの WT ドキュメントを掘り下げて、これまで手ぶらでやってきたので、WT についてもっと知っている人がここで私を助けてくれるかもしれません。

とにかく、ブースト スレッドの WComboBox ウィジェットがクリックされたときにデータが更新されず、選択が変更されるという問題があります。

クラスにブースト スレッドを作成しました

    class MyConsole: public WApplication
    {
    private:
    boost::shared_ptr<boost::thread> _thread;
    WComboBox* _combo_box;
    bool running;

    //Thread function
    void my_thread(Wt::WApplication *app);
    }

次に、コンボ ボックスにデータを入力します。「foo」と「goya」を 2 つのエントリとして使用します。スレッドの関数を作成し、ループを入れました。

    void MyConsole::my_thread(Wt::WApplication *app)
    {
     while(running)
     {
      std::string test;
      Wt::WApplication::UpdateLock lock(app);
      if(lock)
      {
       test = _combo_box->valueText().narrow();
      }
      if (strcmp("foo", test.c_str()) == 0)
      {
        cout << "we got foo" << endl;
      }
      else if (strcmp("goya", test.c_str()) == 0)
      {
        cout << "we got goya" << endl;
      }
     }
    }

コンボ ボックスの最初の選択を変更しないと、上記のコードは常に foo if ステートメントに入りますが、これは想定どおりです。ただし、_combo_box の選択を「goya」に変更すると、上記のコードは依然として「foo」if ステートメントに入ります。これは非常に予期しないことです。ifステートメントの前にコンボボックスの現在のインデックスを出力するなど、問題をさらに調査すると、常に0であり、選択が変更されてもインクリメントされないことがわかりました。

私がそれを修正した方法は、クラスに追加した何もしない関数にコンボボックスの changed() シグナルを接続することでした。

    class MyConsole: public WApplication
    {
    private:
    ...
    void WWidgetForceUpdate(void)
    {

    }
    ...
    }
    ...
    _combo_box->changed().connect(this, &MyConsole::WWidgetForceUpdate);

選択が変更されたときのその関数呼び出しの追加により、"foo" および "goya" if ステートメントは適切に機能し、if ステートメントの前にコンボ ボックスの現在のインデックスを出力して、インデックスが現在変更されていることを確認しました。

changed() シグナルを何もしない関数に接続すると、状況が改善されたのはなぜですか? ここには見られない大きな問題があると確信しています:(どんな助けも大歓迎です。

4

1 に答える 1

1

イベントが発生すると、Wt はブラウザーからサーバーに変更を送信します。プログラムがイベントに関心がない場合、この同期は行われません (そうしないと、入力ボックスに入力したテキストのすべての文字、マウスの動きごとに同期が行われます....アプリケーションが実行していなくても)それと何でも)。changed() に何も接続されていないということは、その特定のイベントに関心のあるものが何もないことを意味し、ブラウザはそれが発生したときにサーバーに通知しません。

リッスンされているイベントはすべて、すべてのウィジェットのすべての変更をサーバーに送信するため、完全なウィジェット ツリーが同期されます。したがって、clicked() リスナーを含むボタンと、changed() リスナーを含まないコンボボックスがある場合、ボタンをクリックすると、ウィジェット ツリーでコンボボックスの状態が更新されます。

ただし、コードにはバグがあります。更新ロック (WApplication::UpdateLock) を取得せずにランダム スレッドからウィジェット ツリーにアクセスすることはできません。

于 2013-04-03T09:47:52.227 に答える