私はget_wifi_ssids()
のメソッドConnectionManager
を持っており、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;
}
私のアプリケーション全体が1つのスレッドに含まれています。 "connman"は、DBusを介してWifiConroller
によって命令されています。それは明らかに別のスレッドに分かれています。 GUIは別のプロセスで実行され、私のアプリケーションはDBus経由で通信します。
QEventLoop
は、生産に使用されることを意図したものではなく、ハックの多くであるため、悪い解決策です。this answerのコメントによると、
本当に** get_wifi_ssids()からのリストを返さなければなりませんか?代わりにシグナルが利用可能なときにリストを表示しないでください。それらを返す場合は、ネストされたイベントループを開始するか、スレッド全体でブロックするかのいずれかで、リストが利用可能になるまで何らかの形で関数内で停止する必要があります(これはさらに推奨されません)。 – Mike
利用可能な場合は、リストで信号を発信することをお勧めします。あなたのクラスにリストを格納して、あなたのクラスからの最後の利用可能な結果を得るためにあなたのオブザーバーのためのシグナルを出してください(['QIODevice :: readyRead()'](https://doc.qt.io/qt -5/qiodevice.html#readyRead)シグナルの動作)。 – Mike
@Mike Hmmそれは良い提案です。しかし、スレッドをブロックすることは悪い考えです(つまり、スキャンが完了するまでスピンロックを使用するなど)。私はGUIスレッドを持っていません(それは別のプロセスで実行されており、私のアプリケーションはDBus経由でそれに話しています)。 – DBedrenko