У меня есть класс ConnectionManager
с методом get_wifi_ssids()
, который должен вернуть список SSID. Проблема в том, что для получения этих SSID необходимо использовать сигналы и слоты, но я не могу найти способ получить эту информацию без первого выхода из метода.Как сделать способ отправить сигнал и дождаться слота перед возвратом?
Вот иерархия классов, используемых с самого низкого уровня до самого высокого.
/** Controls wireless network card by commanding a software component "connman" via DBus. */
class WifiController : QObject {
Q_OBJECT
public:
void scan();
}
/** Low level interface to network interfaces. */
class NetworkController : QObject {
Q_OBJECT
public:
void scan_for_wifi() {
wifi_controller.scan();
// When scan is finished it sends the
// NetworkTechnology::scanFinished signal.
}
// Gets info from cache. This cache is updated when a `scan()` happens.
QList<AccessPointInfo> get_available_access_points;
private:
WifiController wifi_controller;
}
/** High level interface to network interfaces. */
class ConnectionManager {
public:
QList<QString> get_wifi_ssids() {
netCtrlr.scan();
// PROBLEM HERE: How do I wait for the `scanFinished` signal here, then
// continue execution and return the SSIDs from the recently-updated
// cache?
QList<AccessPointInfo> APs { netCtrlr.get_available_access_points() };
QList<QSitrng> ssids { parseAPInfo(APs) };
return ssids;
}
private:
NetworkController netCtrlr;
}
В целом мое приложение находится в одной теме. «connman» управляется WifiConroller
через DBus, и это отдельный процесс, очевидно, в отдельном потоке. GUI запускается в отдельном процессе, и мое приложение общается с ним через DBus.
A QEventLoop
- это плохое решение, потому что оно не предназначено для использования в производстве и является скорее взломом, в соответствии с комментариями в this answer.
Вы действительно должны ** вернуть ** список из 'get_wifi_ssids()'? почему бы не испускать список в сигнале, когда они доступны? Если вы хотите вернуть их, вам нужно как-то остановиться внутри функции до тех пор, пока список не будет доступен, либо запустив вложенный цикл событий (и это обескураживает), либо блокируя весь поток (и это еще более обескураживает). – Mike
Я бы предложил излучать сигнал со списком, когда он доступен. Или сохраните список в своем классе и выпустите сигнал для своего наблюдателя, чтобы получить последний доступный результат от вашего класса (что-то вроде того, как ['QIODevice :: readyRead()'] (https://doc.qt.io/qt -5/qiodevice.html # readyRead) работает). – Mike
@Mike Хм, это хорошее предложение. Но почему вы говорите, что блокирование потока - плохая идея (т. Е. Использование спин-блокировки для ожидания завершения сканирования)? У меня нет потока GUI (он работает в отдельном процессе, и мое приложение говорит с ним через DBus). – DBedrenko