From 6403ead91ee0f4060deefd5a35b2a5cf563d3258 Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Tue, 28 Mar 2023 16:41:26 +0200 Subject: LowEnergyScanner example: allow stopping device discovery ... and also show the newly-discovered devices as soon as they are discovered. This requires a more complex logic for updating the device list, because the deviceDiscovered() signal can be emitted multiple times for the same device. Task-number: QTBUG-111972 Pick-to: 6.5 Change-Id: I8e5f839ffb679516819d8f6063393d5a9b0ec840 Reviewed-by: Juha Vuolle --- examples/bluetooth/lowenergyscanner/Devices.qml | 29 ++++++++++------ examples/bluetooth/lowenergyscanner/device.cpp | 40 +++++++++++++++------- examples/bluetooth/lowenergyscanner/device.h | 7 ++-- .../lowenergyscanner/doc/src/lowenergyscanner.qdoc | 4 +++ 4 files changed, 53 insertions(+), 27 deletions(-) (limited to 'examples') diff --git a/examples/bluetooth/lowenergyscanner/Devices.qml b/examples/bluetooth/lowenergyscanner/Devices.qml index 594e6b7d..40afce7f 100644 --- a/examples/bluetooth/lowenergyscanner/Devices.qml +++ b/examples/bluetooth/lowenergyscanner/Devices.qml @@ -22,7 +22,15 @@ Rectangle { Header { id: header anchors.top: parent.top - headerText: "Start Discovery" + headerText: { + if (Device.state) + return "Discovering" + + if (Device.devicesList.length > 0) + return "Select a device" + + return "Start Discovery" + } } Dialog { @@ -50,11 +58,6 @@ Rectangle { border.color: "black" radius: 5 - Component.onCompleted: { - info.visible = false - header.headerText = "Select a device" - } - MouseArea { anchors.fill: parent onClicked: { @@ -103,11 +106,15 @@ Rectangle { menuHeight: (parent.height / 6) menuText: Device.update onButtonClick: { - Device.startDeviceDiscovery() - // if startDeviceDiscovery() failed Device.state is not set - if (Device.state) { - info.dialogText = "Searching..." - info.visible = true + if (!Device.state) { + Device.startDeviceDiscovery() + // if startDeviceDiscovery() failed Device.state is not set + if (Device.state) { + info.dialogText = "Searching..." + info.visible = true + } + } else { + Device.stopDeviceDiscovery() } } } diff --git a/examples/bluetooth/lowenergyscanner/device.cpp b/examples/bluetooth/lowenergyscanner/device.cpp index 0d72458b..a3c6e106 100644 --- a/examples/bluetooth/lowenergyscanner/device.cpp +++ b/examples/bluetooth/lowenergyscanner/device.cpp @@ -29,6 +29,8 @@ Device::Device() this, &Device::deviceScanError); connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &Device::deviceScanFinished); + connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, + this, &Device::deviceScanFinished); //! [les-devicediscovery-1] setUpdate(u"Search"_s); @@ -64,33 +66,46 @@ void Device::startDeviceDiscovery() devices.clear(); emit devicesUpdated(); - setUpdate(u"Scanning for devices ..."_s); //! [les-devicediscovery-2] discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); //! [les-devicediscovery-2] if (discoveryAgent->isActive()) { + setUpdate(u"Stop"_s); m_deviceScanState = true; Q_EMIT stateChanged(); } } +void Device::stopDeviceDiscovery() +{ + if (discoveryAgent->isActive()) + discoveryAgent->stop(); +} + //! [les-devicediscovery-3] void Device::addDevice(const QBluetoothDeviceInfo &info) { - if (info.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) - setUpdate(u"Last device added: "_s + info.name()); + if (info.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) { + auto devInfo = new DeviceInfo(info); + auto it = std::find_if(devices.begin(), devices.end(), + [devInfo](DeviceInfo *dev) { + return devInfo->getAddress() == dev->getAddress(); + }); + if (it == devices.end()) { + devices.append(devInfo); + } else { + auto oldDev = *it; + *it = devInfo; + delete oldDev; + } + emit devicesUpdated(); + } } //! [les-devicediscovery-3] void Device::deviceScanFinished() { - const QList foundDevices = discoveryAgent->discoveredDevices(); - for (auto &nextDevice : foundDevices) - if (nextDevice.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) - devices.append(new DeviceInfo(nextDevice)); - - emit devicesUpdated(); m_deviceScanState = false; emit stateChanged(); if (devices.isEmpty()) @@ -315,18 +330,17 @@ void Device::serviceDetailsDiscovered(QLowEnergyService::ServiceState newState) void Device::deviceScanError(QBluetoothDeviceDiscoveryAgent::Error error) { - if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError) + if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError) { setUpdate(u"The Bluetooth adaptor is powered off, power it on before doing discovery."_s); - else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError) + } else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError) { setUpdate(u"Writing or reading from the device resulted in an error."_s); - else { + } else { static QMetaEnum qme = discoveryAgent->metaObject()->enumerator( discoveryAgent->metaObject()->indexOfEnumerator("Error")); setUpdate(u"Error: "_s + QLatin1StringView(qme.valueToKey(error))); } m_deviceScanState = false; - emit devicesUpdated(); emit stateChanged(); } diff --git a/examples/bluetooth/lowenergyscanner/device.h b/examples/bluetooth/lowenergyscanner/device.h index ea5d6ed6..d15b02dc 100644 --- a/examples/bluetooth/lowenergyscanner/device.h +++ b/examples/bluetooth/lowenergyscanner/device.h @@ -53,6 +53,7 @@ public: public slots: void startDeviceDiscovery(); + void stopDeviceDiscovery(); void scanServices(const QString &address); void connectToService(const QString &uuid); @@ -87,9 +88,9 @@ private: void setUpdate(const QString &message); QBluetoothDeviceDiscoveryAgent *discoveryAgent; DeviceInfo currentDevice; - QList devices; - QList m_services; - QList m_characteristics; + QList devices; + QList m_services; + QList m_characteristics; QString m_previousAddress; QString m_message; bool connected = false; diff --git a/examples/bluetooth/lowenergyscanner/doc/src/lowenergyscanner.qdoc b/examples/bluetooth/lowenergyscanner/doc/src/lowenergyscanner.qdoc index 7a55f5e9..4a9bff9e 100644 --- a/examples/bluetooth/lowenergyscanner/doc/src/lowenergyscanner.qdoc +++ b/examples/bluetooth/lowenergyscanner/doc/src/lowenergyscanner.qdoc @@ -53,6 +53,10 @@ device. It filters all found devices which have the \l QBluetoothDeviceInfo::LowEnergyCoreConfiguration flag and adds them to a list which is shown to the user. + The \l {QBluetoothDeviceDiscoveryAgent::}{deviceDiscovered()} signal may be + emitted multiple times for the same device as more details are discovered. + Here we match these device discoveries so that the user only sees the + individual devices: \snippet lowenergyscanner/device.cpp les-devicediscovery-3 -- cgit v1.2.1