C++ 如何在信号槽中设置等待条件?

C++ 如何在信号槽中设置等待条件?,c++,qt,signals-slots,C++,Qt,Signals Slots,我正在做一个网络相关的项目。最近我偶然发现了这种情况。这只是一个存根 Class My_Class { public: My_Class(); void start(); public slots(): void after_Load_Function(); } My_Class::My_Class() { //Some initializations connect(WebPage,SIGNAL(finished()),this,SLOTS(after

我正在做一个网络相关的项目。最近我偶然发现了这种情况。这只是一个存根

Class My_Class
{
public:
    My_Class();
    void start();
public slots():
    void after_Load_Function();
}

My_Class::My_Class()
{
    //Some initializations
    connect(WebPage,SIGNAL(finished()),this,SLOTS(after_Load_Function()));
}

void My_Class::start()
{
    WebPage->load();
}

void My_Class::after_Load_Function()
{
    //Do something with the finished WebPage
}

int main(int argc,char * argv[])
{
    //Some Qt things

    My_Class a;
    a.start();
}
“网页”满载时发出“完成”信号。 现在的问题是,在“网页”加载之前,“开始”正在返回。因此,控制到达“主”。因此,现在控件应该在“加载函数”完成其任务后才从“开始”返回。因此,我想要下面的顺序

  • main创建My_类对象A
  • 主呼叫从A开始
  • start从“WebPage”调用load,并等待“WebPage”发出“finished”, 该函数依次调用“after_Load_函数”和“after_Load_函数”
    完成它的工作
  • 现在,“开始”又回来了
  • 主要收益

  • 但是,我不知道如何使这种等待条件。我该怎么做呢?

    你不应该在UI代码中等待。您需要将“main”函数分解为若干部分,以便后面的部分可以单独执行。

    使用这些函数就是它们的用途。您可以让线程等待条件变量并在收到通知时继续执行。

    您可以通过运行本地事件循环,让组件处理网络收入并加载页面来完成此操作。当它们发出信号时,您在事件循环上执行一个插槽以退出它

    void My_Class::start()
    {
        QEventLoop qel;
        QObject::connect(WebPage, SIGNAL(finished()), &qel, SLOT(quit()));
    
        WebPage->load();
        qel.exec();
    }
    
    我以前用过这个,效果很好。但是我不建议经常使用它,因为它将处理事件,包括调用
    start
    的调用方可能不希望处理的事件,因此您需要将此记录给调用方。通过将某些标志传递给
    QEventLoop::exec
    ,可以阻止某些事件的处理,就像阻止处理用户界面事件一样。

    方法是异步的,
    WebPage->load()
    意味着它会立即运行,而不是在加载完成时运行。当您执行其他操作时,该操作将在后台运行

    这被认为是一件好事,因为它使你的应用程序更具响应性,完成更多任务。例如,如果你的应用程序有一个GUI,你可以用某种表示正在检索网页的动画来更新GUI

    如果你喜欢一个模型,在这个模型中,应用程序块直到页面被完全加载,然后考虑做出这样的改变:

    void My_Class::start()
    {
        WebPage->load();
        while (!WebPage->isLoaded())
            Sleep(1);
        after_Load_Function();
    }
    
    注:

    • Sleep
      功能将在Windows上工作。如果您使用的是Unix操作系统,则可以使用
      usleep
    • 由于此函数将在加载网页之前有效阻止,因此没有理由使用来自网页对象的信号,您只需在等待完成后调用处理程序,因为这将使处理程序在同一线程中运行
    • 这样做真是糟糕的做法。如果你的程序是命令行,没有GUI和/或事件循环,你可能会侥幸逃脱,但是你应该考虑一个更好的设计,在这个应用程序中,网页的加载不会阻塞整个应用程序。

    什么是
    网页
    ?如果它基于Qt-Webkit类,那么它很可能依赖于事件循环来运行,以便能够完成。阻塞
    start
    会阻止这种情况,从而使应用程序死锁。您为什么要等待该事件?仅略过这个问题,似乎是关于某些第三方图书馆设施,即RTFM所涵盖的。@Mat问题是在“网页”加载之前,“开始”是returning@prabhakaran当前位置我理解正在发生的事情,但不理解为什么这是一个问题。在Qt中阻塞主线程通常是错误的,并且会使应用程序死锁。为什么你不能做任何需要在插槽中完成的事情(甚至以后)?网页依赖于事件循环吗?@Alf在这个项目中,我只使用Qt。除了你不应该让主线程在UI应用程序中等待之外。