注意:我的原帖有一个重要的遗漏:我遗漏了我已经在main的开头实例化了主QApplication
实例。创建两个QApplication
实例是导致问题的原因。使用相同的QApplication
实例而非创建两个实例来解决问题。
我的目的是在主应用程序之前运行QApplication
以迭代可用的蓝牙设备,以找到特定的蓝牙设备。如果在特定时间限制内未找到特定时间,则QApplication
将终止。调用startDiscovery
后立即调用第一个存储的lambda(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();
}
答案 0 :(得分:1)
答案:discoveryAgent->start();
基本上阻止了你的主线程。这就是为什么,由QTimer::singleShot(BLUETOOTH_DISCOVERY_TIMEOUT, cancelDiscovery);
发布的事件永远不会被处理 - 应用程序执行discoveryAgent->start()
并且没有机会查看事件循环。
答案 1 :(得分:0)
我的原帖有一个重要的遗漏:我遗漏了我已经在main的开头实例化了主要的QApplication实例。创建两个QApplication实例是导致该问题的原因。使用相同的QApplication实例而不是创建两个修复问题。