我有一個類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