jeudi 24 août 2017

QTimer::singleShot only calling lamdba when interval is 0

My intention is to run a QApplication before the main application to iterate the available bluetooth devices, to find a specific one. If the specific one is not found in a certain time limit, the QApplication is terminated. The first stored lambda (startDiscovery) is called as soon as QApplication::exec() is called, but the second stored lamda (cancelDiscovery) is never called! The relevant section is below:

#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[])
{    
    //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...

}

Aucun commentaire:

Enregistrer un commentaire