c++ - QTimer::singleShot 仅在间隔为 0 时调用 lambda

标签 c++ qt c++11 qt5

注意:我的原始帖子有一个重要的遗漏:我遗漏了我已经在 main 的开头实例化了主 QApplication 实例。创建两个 QApplication 实例是导致问题的原因。使用相同的 QApplication 实例而不是创建两个实例解决了这个问题。

我的意图是在主应用程序之前运行一个 QApplication 来迭代可用的蓝牙设备,以找到一个特定的设备。如果在特定的时间限制内没有找到特定的,则终止 QApplication。第一个存储的 lambda (startDiscovery) 在 QApplication::exec() 被调用时被调用,但是第二个存储的 lambda (cancelDiscovery)永远不会被调用!相关部分如下:

#include <QtBluetooth/QBluetoothDeviceInfo>
#include <QtBluetooth/QBluetoothDeviceDiscoveryAgent>
#include <QtBluetooth/QBluetoothLocalDevice>
#include <QTimer>
#include <QString>
#include <QApplication>

#include <memory>
#define TARGET_BLUETOOTH_DEVICE_NAME "MyBluetoothDevice"  
#define BLUETOOTH_DISCOVERY_TIMEOUT 5000 //5 second timeout

int main(int argc, char *argv[])
{    
    std::shared_ptr<QApplication> mainApplication{std::make_shared<QApplication>(argc, argv)};
    //Error checking for no adapters and powered off devices 
    //omitted for sake of brevity
    auto bluetoothAdapters = QBluetoothLocalDevice::allDevices();
    std::shared_ptr<QBluetoothLocalDevice> localDevice{std::make_shared<QBluetoothLocalDevice>(bluetoothAdapters.at(0).address())};

    std::shared_ptr<QBluetoothDeviceDiscoveryAgent> discoveryAgent{std::make_shared<QBluetoothDeviceDiscoveryAgent>(localDevice.get())};
    std::shared_ptr<QBluetoothDeviceInfo> targetDeviceInfo{nullptr};

    std::shared_ptr<QApplication> findBluetooth{std::make_shared<QApplication>(argc, argv)};
    auto setTargetDeviceInfo = [=](QBluetoothDeviceInfo info) {
        if (info.name() == TARGET_BLUETOOTH_DEVICE_NAME) {
            targetDeviceInfo = std::make_shared<QBluetoothDeviceInfo>(info);
            discoveryAgent->stop();
            findBluetooth->exit(0);
        }
    };

    auto cancelDiscovery = [=]() {
        discoveryAgent->stop();
        findBluetooth->exit(1);
    };

    auto startDiscovery = [=]() {
        discoveryAgent->start();
    };

    QObject::connect(discoveryAgent.get(), &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, setTargetDeviceInfo);
    QTimer::singleShot(0, startDiscovery); //startDiscovery get called fine
    QTimer::singleShot(BLUETOOTH_DISCOVERY_TIMEOUT, cancelDiscovery); //cancelDiscovery never gets called!

    findBluetooth->exec();

    //Now check if targetDeviceInfo is nullptr and run the real application etc...
    mainApplication->exec();

}

最佳答案

回答:discoveryAgent->start(); 基本上阻塞了你的主线程。这就是为什么 QTimer::singleShot(BLUETOOTH_DISCOVERY_TIMEOUT, cancelDiscovery); 发布的事件永远不会被处理 - 应用程序执行 discoveryAgent->start() 并且没有机会查看事件循环。

关于c++ - QTimer::singleShot 仅在间隔为 0 时调用 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45864242/

相关文章:

c++ - 为什么在这段代码中没有调用复制构造函数,而是调用了默认构造函数?

c++ - 访问 Qtableview 中的复选框

c++ - 如何编写可变参数模板递归函数?

c# - 与 C# 相比,C++ 中的构造函数和析构函数

c++ - makefile 不适用于 -std=c++11 选项

c++ - Qt - 从主窗口显示第二个窗口

C++ BOOST 库和捆绑属性

c++ - std::weak_ptr::operator= 困惑

c++ - 具有零大小数组的 std::swap() 的编译错误?

c++ - 程序查找并打印最后两位数字均为奇数的第一个完全正方形 (i*i)