繁体   English   中英

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

[英]QTimer::singleShot only calling lambda when interval is 0

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

我的意图是在主应用程序之前运行QApplication来迭代可用的蓝牙设备,以找到特定的设备。 如果在特定时限内找不到特定的应用程序,则QApplication终止。 调用QApplication::exec() ,将立即调用第一个存储的lambda( startDiscovery ),但永远不会调用第二个存储的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);发布的事件QTimer::singleShot(BLUETOOTH_DISCOVERY_TIMEOUT, cancelDiscovery); 永不处理-应用程序正在执行discoveryAgent->start()并且没有机会查看事件循环。

我的原始帖子有一个重要的遗漏:我省略了已经在main的开头实例化main QApplication实例的情况。 导致此问题的原因是创建两个QApplication实例。 使用相同的QApplication实例而不是创建两个实例可以解决此问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM