Qt 插槽未被调用

Posted

技术标签:

【中文标题】Qt 插槽未被调用【英文标题】:Qt Slot not being Called 【发布时间】:2013-03-23 16:47:52 【问题描述】:

我有一个程序,在该程序中,我使用 QSignalMapper 将多个信号从对象连接到主程序中的插槽:

class A()

    private:
        QSignalMapper * signalMapperRead_;
        std::vector<Service*> services_;
    public:
    void initConnection()
    
        signalMapperRead_ = new QSignalMapper();

        connect(signalMapperRead_, SIGNAL(mapped(int)), this, SLOT(readyToSendToService(int)));

        for ( size_t i = 0 ; i < services_.size() ; ++i )
        
            connect(services_.at(i), SIGNAL(readyToSendToServer()), signalMapperRead_, SLOT(map()));
            signalMapperRead_->setMapping(services_.at(i), (int)i);
        
    

    int run()
    
        initConnection();
        for(;;)
        
             //do stuff;
        
    

;

int main()

    QApplication app(argc, argv);
    A * a  = new A();
    a->run();
    return app.exec

然后,由于程序是一种服务器,我让他循环,并等待新的客户端,...

但插槽永远不会被调用。我在想可能是因为程序总是在循环中,从不检查是否发出了信号。

你能帮帮我吗

【问题讨论】:

逐步调试可能有帮助吗? 执行是否离开run() 程序结束,除了那个没有。 也许我可以在运行中的每个循环周期中启动一个 QeventLoop,并在一个小的 timout 中启动 什么是'signalMapperSend_'? 【参考方案1】:

不要使用自己的循环,创建一个 QApplication 并调用它的 exec() 方法。

您必须致电 QApplication::exec() 让 Qt 传递信号。

编辑更改的代码:只需删除 for(;;)-Loop,这是不必要的。 QApplication::exec() 有自己的循环。

【讨论】:

【参考方案2】:

但是这个槽永远不会被调用。

关于QApplication::exec 的Qt 文档说:

进入主事件循环并等待直到调用 exit() [...]。 需要调用此函数来启动事件处理。主事件循环从窗口系统接收事件并将这些事件分派给应用程序小部件。 [...] 通常,在调用 exec() 之前不会发生任何用户交互。 [...]

这意味着是 exec 方法负责处理信号槽系统。您正在调用 A::run(在 exec 函数之前),其中包含一个 for(;;) 无限循环,它将阻止执行真正的循环,从而导致您的信号丢失。

【讨论】:

【参考方案3】:

我找到了解决方法。除了我不确定它是否非常有效之外,我的解决方案是在我的for(;;) 循环的每个循环中启动一个QEventLoop,并且我在QTimer 超时时使这个QEventLoop 退出

【讨论】:

为什么不使用QApplication 事件循环而不是实现自己的?您正在为自己制造工作和问题。 已经放下你自己的循环。它所做的只是用无用的工作烧掉你的 CPU。在每次循环迭代中创建(和删除)一个完整的 QApplication 对象并不能让它变得更好。 我必须使用我自己的循环,因为这是一个学校项目,我们可以使用 Qt 做一些事情,但例如我们不能使用 QThread。

以上是关于Qt 插槽未被调用的主要内容,如果未能解决你的问题,请参考以下文章

从 JavaScript 调用 Qt 插槽

未连接的 Qt 插槽被调用

Qt:没有从第二个线程调用插槽

Qt 插槽同时断开连接并从不同线程调用

Qt 插槽,调用没有匹配函数

未调用 Qt moveToThread 插槽