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 回答