我遇到了一个有趣的 WT 问题,我已经解决了它,但我不明白为什么我的解决方案解决了这个问题。我已经翻阅了小部件的 WT 文档,但到目前为止还是空手而归,所以也许对 WT 了解更多的人可以在这里帮助我。
无论如何,问题在于 boost 线程中的 WComboBox 小部件在单击并更改其选择时未更新其数据。
我在一个类中创建了一个boost线程
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() 信号连接到一个什么都不做的函数可以解决这个问题?我确定这里有一个更大的问题我没有看到:( 任何帮助将不胜感激。
最佳答案
Wt 在事件发生时将更改从浏览器发送到服务器。如果您的程序对某个事件不感兴趣,则不会发生此同步(否则同步将发生在您在输入框中输入的文本的每个字符上,在每个鼠标移动上,......即使您的应用程序没有做任何东西)。 Nothing connected to changed() 意味着没有人对该特定事件感兴趣,浏览器不会在它发生时通知服务器。
任何正在监听的事件都会将所有小部件的所有更改发送到服务器,以便同步完整的小部件树。因此,如果您有一个带有 clicked() 监听器的按钮和一个没有 changed() 监听器的组合框,则当您单击按钮时,组合框的状态仍会在小部件树中更新。
然而,您的代码中存在一个错误:您不能在不获取更新锁 (WApplication::UpdateLock) 的情况下从随机线程访问小部件树。
关于c++ - WT 小部件未在 boost 线程中更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15774153/