【问题标题】:Qt: either signal won't send, or slot is not calledQt:要么信号不会发送,要么插槽没有被调用
【发布时间】:2021-10-24 16:59:04
【问题描述】:

我在这个问题中隐含了两个 Qt 类:MainWindowotaManager
我想从otaManager 发送一个信号,并让MainWindow 在它发送时调用一个插槽。
这里是MainWindow.h (https://github.com/Kobo-InkBox/inkbox/blob/1d48a6d85ee5b0a4db86c1d9f49510d0d923b297/mainwindow.h#L104):

private slots:
    void openUpdateDialogOTA(bool open);
    ...

private:
    ...
    otaManager *otaManagerWindow;

MainWindow.cpp(https://github.com/Kobo-InkBox/inkbox/blob/1d48a6d85ee5b0a4db86c1d9f49510d0d923b297/mainwindow.cpp#L979-L993):

...
void MainWindow::openUpdateDialogOTA(bool open) {
    if(open == true) {
        global::otaUpdate::isUpdateOta = true;
        openUpdateDialog();
    }
    else {
        ;
    }
}


void MainWindow::launchOtaUpdater() {
    otaManagerWindow = new otaManager(this);
    connect(otaManagerWindow, SIGNAL(canOtaUpdate(bool)), SLOT(openUpdateDialogOTA(bool)));
    otaManagerWindow->setAttribute(Qt::WA_DeleteOnClose);
}

otaManager.h(https://github.com/Kobo-InkBox/inkbox/blob/1d48a6d85ee5b0a4db86c1d9f49510d0d923b297/otamanager.h#L21-L22):

...
signals:
    void canOtaUpdate(bool yesno);
...

otaManager.cpp (https://github.com/Kobo-InkBox/inkbox/blob/1d48a6d85ee5b0a4db86c1d9f49510d0d923b297/otamanager.cpp#L15-L30):

        ...
        if(global::otaUpdate::downloadOta != true) {
            string_writeconfig("/opt/ibxd", "ota_update_check\n");
            while(true) {
                if(QFile::exists("/run/can_ota_update") == true) {
                    if(checkconfig("/run/can_ota_update") == true) {
                        emit canOtaUpdate(true);
                        qDebug() << "OTA update is available!";
                        break;
                    }
                    else {
                        emit canOtaUpdate(false);
                        qDebug() << "No OTA update available.";
                        break;
                    }
                }
            }
       ...

程序编译运行后,通过otaManager中的所有条件,输出“OTA更新可用!”通过 QDebug 调用消息。
虽然,在接收信号时 MainWindow 没有调用插槽,或者它没有被发送,因为 MainWindow 中的 openUpdateDialogOTA 函数,即使我进行了一些 QDebug 调用以查看它是否已启动,也不输出也不做任何事。

我对这一切感到很困惑,因为我对项目中的其他类也是这样做的,而且效果很好。

【问题讨论】:

  • 您确定在 MainWindow 收到信号之前没有关闭 otaManagerWindow 吗?你试过评论otaManagerWindow-&gt;setAttribute(Qt::WA_DeleteOnClose);吗?
  • 我在课堂上进一步评论了otaManager::close() 电话,但它没有用。而且我刚刚试了你说的也没有任何效果。
  • 目前看不出原因。你说你确实验证了 openUpdateDialogOTA() 肯定没有通过将 qDebug() 放在该函数的顶部来调用正确吗?
  • 是的。我在它的顶部放了一个qDebug() &lt;&lt; "Got there"。当从主线程而不是从信号调用时,它可以工作。我还尝试了另一个测试信号/插槽对,也没有任何反应。
  • 您是否尝试在MainWindow 类的构造函数中将SIGNAL 与SLOT 连接起来?

标签: c++ qt signals-slots qt-signals


【解决方案1】:

您忘记了接收器对象:

connect(otaManagerWindow, SIGNAL(canOtaUpdate(bool)), SLOT(openUpdateDialogOTA(bool)));

尝试使用新风格的连接方法:

connect(a, &A::OnSignal, b, &B::OnSlot);

【讨论】:

  • 你是这个意思? connect(otaManagerWindow, &amp;otaManager::canOtaUpdate, this, &amp;MainWindow::openUpdateDialogOTA); 也不行。
  • 尝试删除构建文件夹。
  • 您是否尝试像没有emit 的方法一样调用您的signal
  • 不,那会怎样?
  • emit 是语法糖。也许你的情况很糟糕。只是我试着思考。
【解决方案2】:

看来while(true) 循环是罪魁祸首。我仍然不知道为什么,我想知道这是否正常。我改为使用 QTimer 实现,您可以在此处看到:https://github.com/Kobo-InkBox/inkbox/blob/1f539e6bf3020d2a4069295133e0cd470efb8ca9/otamanager.cpp
现在发送信号没有任何问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 2016-11-10
    相关资源
    最近更新 更多