2009-09-14 14 views
11

QDbusAbstractInterface(qdbusxml2cpp経由)上に構築されたQt DBusプロキシを使用して、開始するときにインターフェイスしたいサービス/オブジェクトを処理する最善の方法は何ですか?注:私は単にそれを知ることに興味がありません(BlahService.isValid()を使ってそれを見つけることができます)。私はそれが有効かどうかを知ることができ、それが有効になったときに状態を変えることができるようにしたいと思っています。逆に、同様の理由でそれがもはや有効ではないことを知りたい。その後、私たちはその信号変化の状態を取得する -QtでDBusサービスを利用できるようになるのを待つ

#define CONNECT_DBUS_SIG(x,y) connect(blah,SIGNAL(x),this,SLOT(y)) 

// FIX - should watch for service, and also handle it going away and 
// coming back 
blah = new BlahService("com.xyzzy.BlahService", "/com/xyzzy/BlahService", 
          QDBusConnection::sessionBus(), this); 
if (!blah) 
    return 0; 
if (blah.isValid()) 
{ 
    CONNECT_DBUS_SIG(foo(),Event_foo()); 
} 
else 
{ 
    // Since we aren't watching for registration, what can we do but exit? 
} 

おそらく、我々はDバス接続オブジェクトにNameOwnerChangedを監視する必要がある - QTのdbusのコードが私たちのためにこれを行いますしない限り:サービスの状態を追跡することなく

必要に応じて、オブジェクトから信号を接続または切断します。

私が見つけたすべての例では、問題を無視するか、サーバーオブジェクトが存在しない場合は終了し、それを処理しません。車/コントローラのQtの例では、サーバーがなくなると、使用中にisValid()がfalseになるが、isValid()がポーリングされている場合、少なくとも "Disconnected"と表示されます。

追加さ:QtDbusAbtractInterfaceサーバ(NameOwnerChanged)の所有権の変更、および更新のisValid()の変化が起こるためのレジスタ

注意。だから私はあなたがその所有権の変更について直接調べるためにそのserverOwnerChangedシグナルに直接接続でき、それを再度試みるためのインジケータとして使用することができると考えています - あなたがシグナリングを受ける前または後に更新されるかもしれないのでisValidを信じることはできません。

また、(醜い)あなたはタイマーを設定して、isValid()をポーリングすることができます。

答えて

9

誰も答えないので、私はその間に答えを見つけた、[OK]を:

あなたはNameOwnerChangedを見たい:

// subscribe to notifications about when a service is registered/unregistered 
    connect(QDBusConnection::sessionBus().interface(), 
      SIGNAL(serviceOwnerChanged(QString,QString,QString)), 
      this,SLOT(serviceOwnerChanged(QString,QString,QString))); 

void 
VcsApplicationController::serviceOwnerChanged(const QString &name, 
               const QString &oldOwner, 
               const QString &newOwner) 
{ 
    Q_UNUSED(oldOwner); 
    if (name == "com.foo.bar.FooService") 
    { 
     qLog(Whatever) << "serviceOwnerChanged" << name << oldOwner << newOwner; 
     if (!newOwner.isEmpty()) 
     { 
      // New owner in town 
      emit Initialized(); 
      // or if you control the interface and both sides, you can wait for 
      // a "Ready()" signal before declaring FooService ready for business. 
     } 
     else 
     { 
      // indicate we've lost connection, etc 
      emit Uninitialized(); 
     } 
    } 
} 

注意がことは、serviceOwnerChangedからFooServiceのメソッドを実行して競合状態になる可能性があります。バインディングの副作用があるかどうかはまだ分かりません(dbus-c + +私のテストケースでは++)、またはdbusの設計に固有のものです(dbusメーリングリストの上では問題に答えることはできません)。 が実際の競合状態であるである場合、DBus APIを制御する場合、Ready()/何らかの信号を待つことができます。もう一方の端を制御しない場合、非常に短い遅延を追加することもできますし、AddMatch()を見て、新しい所有者が名前に一致したことを確認することもできます。

+0

この行は、私が望むサービスのシグナルだけを取得するために使用します: 'QDBusConnection :: systemBus()。connect(" org.freedesktop.DBus "、"/org/freedesktop/DBus "、" org.freedesktop。 (QString、QString、QString)); '競合状態に関して、私は競合状態に関して、私は、私の古いインターフェイスを削除し、私はこの信号を取得すると、新しいものを取得します。 – Harvey

3

Qt 5.3の場合、serviceOwnerChangedは推奨されていません。 QDBusServiceWatcherを使用すると、すべてではなく特定のサービスを監視できます。

関連する問題