我有一个类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