0

I have run into an interesting problem with WT, I have solved it, but I do not understand WHY my solution solved the problem. I've dug through WT documentation for the widgets and have come up empty handed so far, so maybe someone who knows more about WT can help me out here.

Anyway, the problem is with a WComboBox widget in a boost thread not updating it's data when clicked on and having it's selection changed.

I created a boost thread in a class

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

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

Then I fill the combo box with data, lets use "foo" and "goya" as the 2 entries. I made a function for the thread, and put a loop into it.

    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;
      }
     }
    }

Without changing the initial selection of the combo box, the above code always enters the foo if statement, which is expected. However, when I change the selection of the _combo_box to "goya" the above code still enters the "foo" if statement, which is very unexpected. Investigating the matter further such as printing out the current index of the combo box before the if statement showed me that it is always 0 and never gets incremented when the selection changes.

The way I fixed it was by connecting the combo box changed() signal to a do nothing function that I added to the class.

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

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

With the addition of that function call when the selection changes, the "foo" and "goya" if statements worked properly, and printing out the current index of the combo box before the if statement confirmed that the index was now changing.

Why did connecting the changed() signal to a do nothing function remedy the situation? I am sure there is a bigger problem that I am not seeing here :( Any help would be much appreciated.

user2115945
  • 223
  • 3
  • 12

1 Answers1

1

Wt sends changes from the browser to the server when events happen. If your program is not interested in an event, this synchronisation will not take place (otherwise synchronisation would take place on every character of text you enter in an input box, on every mose movement, .... even if your application is not doing anything with it). Nothing connected to changed() means that nothing is interested in that specific event, and the browser will not notify the server when it happens.

Any event that is being listened upon will send all changes of all widgets to the server, so that the full widget tree is synchronised. So if you have a button with clicked() listener, and a combobox without a changed() listener, the state of the combobox will still be updated in the widget tree when you click the button.

There is however a bug in your code: you cannot just access the widget tree from a random thread without grabbing the update lock (WApplication::UpdateLock).

user52875
  • 3,020
  • 22
  • 21
  • What you said makes sense, I find it a bit odd that they set up WT this way, I figured it would update its data if the user changed something in the GUI. But, if that's how it's set up then so be it, I'll just keep a do nothing function handy in case I need widgets to update ASAP when the user changes something about it. Also, I added that UpdateLock you mentioned. Thanks again for the help. – user2115945 Apr 03 '13 at 11:12