c++ - 多个 WT 应用程序可以在同一个网页上运行吗?

标签 c++ visual-studio-2010 embed html wt

所以最近我问了一个问题,看看Can multiple WT applications run on same port?答案是肯定的(+1 给 Jorge Núñez 的那个很棒的答案)。但是,现在我正尝试进一步采用他的解决方案,通过将多个 WT 应用程序嵌入到一种主机 WT 应用程序中,看看是否可以在同一页面上运行多个 WT 应用程序。我所做的是创建一个主机 WT 应用程序,它有一个访问器用于它的 root() 和一个 WTabWidget。然后在 CreateHostApplication 函数中,我为 2 个测试应用程序创建了选项卡,它们也有 root() 的访问器,并将它们的 root() 添加到属于我的主机应用程序的选项卡,然后在所有应用程序都添加到它们各自的选项卡之后选项卡,我返回了主机。

最酷的部分是测试应用程序中的小部件如我所料显示在它们的选项卡中,我没想到的是 connect() 调用以将按钮连接到函数失败。因此,就单击它们和编辑框中的文本而言,这些小部件是正常工作的,但它们不执行任何其他操作,因为它们未连接到任何自定义功能。

稍微调试一下后,我很确定测试应用程序上的连接调用失败了,因为它们实际上并非由浏览器托管,这让我来到这里。我还没有找到解决这个问题的方法,有没有办法让连接调用在这个设置下起作用?

下面的代码是 Jorge Núñez 的解决方案,并进行了上述修改。我正在使用 visual studio2010 进行开发。提前感谢您的帮助!

#include <Wt/WApplication>

#include <Wt/WBreak>          
#include <Wt/WContainerWidget>
#include <Wt/WLineEdit>       
#include <Wt/WPushButton>     
#include <Wt/WText>           
#include <Wt/WException>      
#include <Wt/WLogger>         
#include <Wt/WServer>         
#include <Wt/WTabWidget>

using namespace Wt;


class Host : public Wt::WApplication
{
public:
  Host(const Wt::WEnvironment& env);
  WContainerWidget* GetRoot()
  {
    return root();
  }
};
Host::Host(const Wt::WEnvironment& env) : Wt::WApplication(env)
{

}

class TestApp1 : public Wt::WApplication
{
public:
  TestApp1(const Wt::WEnvironment& env, const std::string& title);
  WContainerWidget* GetRoot()
  {
    return root();
  }

private:
  Wt::WLineEdit* _name_edit;
  Wt::WText* _greeting;

  void Greet();
};
TestApp1::TestApp1(const Wt::WEnvironment& env, const std::string& title) : Wt::WApplication(env)
{
  setTitle(title);

  root()->addWidget(new Wt::WText("Your name, please ? "));
  _name_edit = new Wt::WLineEdit(root());

  Wt::WPushButton* button = new Wt::WPushButton("Greet me.", root());
  root()->addWidget(new Wt::WBreak());

  _greeting = new Wt::WText(root());
  button->clicked().connect(this, &TestApp1::Greet);
}
void TestApp1::Greet()
{
  _greeting->setText("Hello there, " + _name_edit->text());
}

class TestApp2 : public Wt::WApplication
{
public:
  TestApp2(const Wt::WEnvironment& env, const std::string& title);
  WContainerWidget* GetRoot()
  {
    return root();
  }

private:    Wt::WLineEdit *_name_edit;
            Wt::WText *_greeting;

            void greet();
};
TestApp2::TestApp2(const Wt::WEnvironment& env, const std::string& title) : Wt::WApplication(env)
{
  setTitle(title);

  root()->addWidget(new Wt::WText("Your name, please ? "));
  _name_edit = new Wt::WLineEdit(root());

  Wt::WPushButton* button = new Wt::WPushButton("Say goodbye.", root());
  root()->addWidget(new Wt::WBreak());

  _greeting = new Wt::WText(root());
  button->clicked().connect(this, &TestApp2::greet);
}
void TestApp2::greet()
{
  _greeting->setText("Goodbye, " + _name_edit->text());
}

Wt::WTabWidget* tab_widget;
Wt::WApplication* CreateHostApplication(const Wt::WEnvironment& env)
{
  Host* host = new Host(env);

  WContainerWidget* root = host->GetRoot();

  tab_widget = new WTabWidget(root);

  //Create tab for the app
  WContainerWidget* Tab_TestApp1 = new WContainerWidget();
  //Get a pointer to the ACE tab
  tab_widget->addTab(Tab_TestApp1, "Test Application 1", Wt::WTabWidget::LoadPolicy::PreLoading);
  //Create app
  TestApp1* test_app_1 = new TestApp1(env, "Test Application 1");
  //Add app root to the tab
  Tab_TestApp1->addWidget(test_app_1->GetRoot());

  //Create tab for the app
  WContainerWidget* Tab_TestApp2 = new WContainerWidget();
  //Get a pointer to the ACE tab
  tab_widget->addTab(Tab_TestApp2, "Test Application 2", Wt::WTabWidget::LoadPolicy::PreLoading);
  //Create app
  TestApp2* test_app_2 = new TestApp2(env, "Test Application 2");
  //Add app root to the tab
  Tab_TestApp2->addWidget(test_app_2->GetRoot());

  return host;
}
Wt::WApplication* CreateTestApp1(const Wt::WEnvironment& env)
{
  return new TestApp1(env, "Test Application 1");
}
Wt::WApplication* CreateTestApp2(const Wt::WEnvironment& env)
{
  return new TestApp2(env, "Test Application 2");
}

int TestWRun(int argc, char* argv[],
  Wt::ApplicationCreator host_application,
  std::vector<Wt::ApplicationCreator> applications)
{
  try 
  {
    // use argv[0] as the application name to match a suitable entry
    // in the Wt configuration file, and use the default configuration
    // file (which defaults to /etc/wt/wt_config.xml unless the environment
    // variable WT_CONFIG_XML is set)
    Wt::WServer server(argv[0],"");

    // WTHTTP_CONFIGURATION is e.g. "/etc/wt/wthttpd"
    server.setServerConfiguration(argc, argv, WTHTTP_CONFIGURATION);

    // add a single entry point, at the default location (as determined
    // by the server configuration's deploy-path)
    server.addEntryPoint(Wt::Application, host_application);

    unsigned int num_apps = applications.size();
    for(unsigned int cur_app = 0; cur_app < num_apps; ++cur_app)
    {
      server.addEntryPoint(Wt::Application, applications[cur_app], "/" + boost::lexical_cast<std::string>(cur_app));
    }

    if (server.start()) 
    {
      int sig = Wt::WServer::waitForShutdown(argv[0]);

      std::cerr << "Shutdown (signal = " << sig << ")" << std::endl;
      server.stop();
    }
  } 
  catch (Wt::WServer::Exception& e) 
  {
    std::cerr << e.what() << "\n";
    return 1;
  } 
  catch (std::exception& e) 
  {
    std::cerr << "exception: " << e.what() << "\n";
    return 1;
  }
}
int main(int argc, char** argv)
{
  std::vector<Wt::ApplicationCreator> applications;
  applications.push_back(&CreateTestApp1);
  applications.push_back(&CreateTestApp2);

  return TestWRun(argc, argv, &CreateHostApplication,  applications);
}

最佳答案

虽然可以使用 Wt,但您的方法并非 100% 正确。 AFAIK 你有两个选择:

  1. 使用 Wt 的 widgetset 模式。查看聊天小部件如何集成在 Wt 的主页上:这是两个独立的 Wt 应用程序,它们同时显示在同一页面上,并且都处于事件状态。与 Google map 小部件相比,Wt 的 widgetset 模式是最好的:您在要呈现应用程序的网页上放置一个小占位符(一个 div + 一些 JS)。参见 examples/wt-home, examples/feature/widgetset
  2. 在 Wt 中,在另一个应用程序中重用一个应用程序的小部件完全没有问题。将您想要重用的部分全部放在 WContainerWidget(或 WCompositeWidget)中,并将其集成到您的 tabwidget 中。实际上,这与您现在正在做的非常相似,但不是采用 TestApp1 的 root(),而是组织您的代码,以便您只将一个小部件放在 TestApp1 的根目录中,并在中使用相同的小部件主机应用程序的选项卡。在 createApplication 中,您不能实例化多个 WApplication 对象。 Widgetgallery 使用这种方法来集成部分图表示例。

关于c++ - 多个 WT 应用程序可以在同一个网页上运行吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16340911/

相关文章:

c++ - 如何在我的应用程序中嵌入和保护一些 "text"文件

iframe - 如何在 youtube Iframe 上禁用全屏?

c++ - 创建任务(): The application called an interface that was marshalled for a different thread

c++ - 我的客户端服务器代码无法正常工作

c# - 当我在 .csproj 文件中使用通配符时,为什么 Intellisense 在 VS2010 中不起作用?

visual-studio-2010 - VS2010和IE10附加脚本调试器处理iexplore.exe失败

visual-studio-2010 - 配置 Visual Studio 2010 远程调试器

java - 独立的 .jar 运行良好,但嵌入 HTML 时,帧速率降至 1 fps

c++ - Qt5:派生QQuickWidget以获取小部件

java - log4j/log4cxx : exclusive 1 to 1 relation between logger and appender