2013-04-02 5 views
0

У меня возникла интересная проблема с WT, я решил ее, но я не понимаю, ПОЧЕМУ мое решение решило проблему. Я вырыл документацию 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» и «Гойя» как 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, если заявление, которое, как ожидается. Однако, когда я изменяю выбор _combo_box на «goya», вышеуказанный код по-прежнему входит в оператор «foo» if, что очень неожиданно. Изучая этот вопрос дальше, например, распечатывая текущий индекс поля со списком до того, как оператор if показал мне, что он всегда равен 0 и никогда не увеличивается при изменении выбора.

Способ, которым я исправил это, подключив сигнал combo box changed(), чтобы ничего не делать, что я добавил в класс.

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

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

С добавлением этого вызова функции при изменении выбора, тем «Foo» и «Гойя», если заявления работали должным образом, и распечатки текущего индекса в поле со списком перед, если заявление подтверждает, что индекс теперь меняется.

Почему соединение с измененным() сигналом ничего не делает, чтобы исправить ситуацию? Я уверен, что есть большая проблема, которую я не вижу здесь :( Любая помощь будет очень признательна.

ответ

1

Wt отправляет изменения из браузера на сервер, когда происходят события. Если ваша программа не заинтересована в событии , эта синхронизация не будет выполняться (в противном случае синхронизация будет происходить на каждом символе текста, который вы вводите в поле ввода, при каждом перемещении mose ... даже если ваше приложение ничего не делает с ним). Ничто не связано с измененным() означает, что ничто не заинтересовано в этом конкретном событии, и браузер не будет уведомлять сервер, когда это произойдет.

Любое событие, которое прослушивается, отправит все изменения всех виджетов на сервер, чтобы полный дерево виджета синхронизируется. Поэтому, если y ou имеет кнопку с нажатым() прослушивателем и combobox без измененного() прослушивателя, состояние combobox все равно будет обновляться в дереве виджета при нажатии кнопки.

Однако в вашем коде есть ошибка: вы не можете просто получить доступ к дереву виджета из случайного потока без захвата блокировки обновления (WApplication :: UpdateLock).

+0

Что вы сказали, имеет смысл, я нахожу несколько странным, что они настроили WT таким образом, я решил, что он обновит свои данные, если пользователь изменит что-то в графическом интерфейсе. Но, если это то, как он настроен, пусть так и будет, я просто не буду делать ничего удобного, если мне нужны виджеты, чтобы обновлять ASAP, когда пользователь что-то изменяет. Кроме того, я добавил, что UpdateLock вы упомянули. Спасибо еще раз за помощь. – user2115945

Смежные вопросы