如何在wt(c ++)中创建后更新网页

时间:2016-09-01 05:50:00

标签: c++ wt

我是wt的新手,刚刚开始在一个lagacy c ++程序中添加web界面。 示例hello_world工作正常。

然而,给出的示例都是关于创建网页,页面可以对来自网页的事件做出反应(即按钮,勾选框),我想在开始会话后修改网页​​。更像是HMI响应数据的变化,而不是来自webpake的按钮。

它应该是可行的,因为wt文件说: 实际的请求处理和呈现是抽象的,可以根据配置和浏览器属性使用整页呈现模型(纯HTML)或增量更新(Ajax / WebSockets)。

我添加一个" updateText" hello_world的方法:

class HelloApplication : public WApplication 
{
public:
    HelloApplication(const WEnvironment& env);
    void updateText(std::string value); // I add this and rest are from helloworld
private:
    WLineEdit *nameEdit_;
    WText *greeting_;
    void greet();
};

以下是实施:

HelloApplication::HelloApplication(const WEnvironment& env)
: WApplication(env) 
{
    setTitle("Trading Platform Status");                               // application title

    root()->addWidget(new WText("Starting... "));  // show some text
    nameEdit_ = new WLineEdit(root());                     // allow text input
    nameEdit_->setFocus();                                 // give focus

    WPushButton *button
        = new WPushButton("Greet me.", root());              // create a button
    button->setMargin(5, Left);                            // add 5 pixels margin

    root()->addWidget(new WBreak());                       // insert a line break

    greeting_ = new WText(root());                         // empty text


    /* Connect signals with slots - simple Wt-way*/
    button->clicked().connect(this, &HelloApplication::greet);

    /* using an arbitrary function object (binding values with boost::bind())*/
    nameEdit_->enterPressed().connect
        (boost::bind(&HelloApplication::greet, this))
}

void HelloApplication::greet() {
    /*Update the text, using text input into the nameEdit_ field.*/
    greeting_->setText("Hello there, " + nameEdit_->text());
}

Greet()来自原始的helloworld,我添加了updateText方法。

void HelloApplication::updateText(std::string value)
{
    /*
    * Update the text, using text input into the nameEdit_ field.
    */
    greeting_->setText(value);
}

WApplication *createApplication(const WEnvironment& env)
{
    /*
    * You could read information from the environment to decide whether
    * the user has permission to start a new application
    */
    return new HelloApplication(env);
}

在主要内容中,我以单独的线程启动主机。

手册指出:

在任何时候都可以使用静态方法WApplication :: instance()访问WApplication实例,并且可以检查启动参数和设置(使用WApplication :: environment()),设置或更改应用程序标题(WApplication :: setTitle()),用于指定用于呈现的语言环境(WApplication :: setLocale())以及许多其他应用程序范围的设置。在多线程环境中,使用线程本地存储实现对此实例的访问。

int main(int argc, char* argv[])
{
    //start in new thread or it blocks the following work
    thread website_thread(&WRun,argc, argv, &createApplication);
    //balabalabala some work
    ((HelloApplication*)WApplication::instance())->updateText("Finished");
    //balabala more work
    return 0
}

updateText失败,因为"这个"一片空白。显然,这不是完成任务的正确方法。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

您需要:

  • 维护您想要发出信号的会话列表,例如通过在构造WApplication时将WApplication对象放在全局列表中,并在析构函数中将其删除。你也可以做得更精细。
  • 为服务器端事件可以更新的每个应用程序启用服务器推送(只需调用WApplication :: enableUpdates())
  • 通过抓取WApplication :: updateLock,或者通过使用WServer :: post()在会话的上下文中发布函数的执行,确保在服务器端修改窗口小部件树时,以某种方式锁定窗口小部件树
  • 在修改小部件树时调用WApplication :: triggerUpdate(),以便将更改推送到客户端

此外,您可能希望在wt_config.xml文件中启用websockets支持。

简单的例子展示了所有这些。

WApplication :: instance使用线程本地存储,当线程被分配来处理会话对象时由Wt设置,因此在主线程中返回null是正常的。