문제

QDBusabStractInterface (QDBUSXML2CPP를 통해)에 구축 된 QT DBUS 프록시를 사용하면 시작할 때 사용할 수없는 상태에서 인터페이스하려는 서비스/객체를 처리하는 가장 좋은 방법은 무엇입니까? 참고 : 나는 단순히 그것을 아는 데 관심이 없다 (blahservice.isvalid ()를 사용하여 그것을 찾을 수 있음); 나는 그것이 유효한 지 알 수 있고 그것이 유효 해지는시기를 알고, 상태를 변경할 수 있도록 (그리고 신호로 상태를 변경 함), 그 상태 변화에서 다른 일을합니다. 반대로, 비슷한 이유로 더 이상 유효하지 않은시기를 알고 싶습니다.

서비스 상태를 추적하지 않고 :

#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?
}

아마도 QT의 DBUS 코드가 우리를 위해이를 수행하지 않는 한 DBUS Connection Object에서 NAMEONERCHANDED를 지켜봐야 할 것입니다. 그리고 그 신호 변경 상태를 얻을 때, 필요한 경우 객체에서 신호를 연결하거나 분리하십시오.

내가 찾은 모든 예는 서버 객체가 존재하지 않으면 문제를 무시하거나 단순히 종료하고 사라지는 것을 다루지 않습니다. CAR/Controller QT 예제는 사용 중에 ISVALID ()가 거짓이되면 서버가 사라지고 "분리 된"인쇄를 인쇄하지만 ISVALID ()를 폴링하는 것입니다.

추가 :

QTDBUSABTRANTINTINGFARE는 서버의 소유권 변경 (NAMEONERCHANGEND)을 등록하고 변경이 발생하면 isValid ()를 업데이트합니다. 따라서 소유권 변경 사항에 대해 직접 해당 서버로 변경 한 신호에 연결하여 다시 시도하기위한 표시기로 사용할 수 있다고 생각합니다. 신호 전후에 업데이트 될 수 있으므로 IsValid를 신뢰할 수는 없습니다.

또는 (못생긴) isvalid ()에 대한 타이머와 폴링을 설정할 수 있습니다.

도움이 되었습니까?

해결책

좋아, 아무도 대답하지 않았기 때문에 그 동안 답을 찾았습니다.

당신은 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();
        }
    }
}

거기에 주목하십시오 5월 ServiceOwnerChanged 내에서 fooservice에 대한 방법을 수행하는 레이스 조건이 있어야합니다. 바인딩의 부작용 (내 테스트 사례에서 DBUS -C ++) 또는 DBUS 설계에 내재 된 경우 아직 확실하지 않습니다 (가능 - NO. DBUS 메일 링리스트에서 질문에 답변합니다). 만약 거기에 ~이다 실제 레이스 조건은 DBUS API를 제어하면 Ready ()/모든 신호를 기다릴 수 있습니다. 다른 쪽 끝을 제어하지 않으면 매우 짧은 지연을 추가하거나 AddMatch ()를보고 새 소유자가 이름에 일치를 추가했는지 확인할 수도 있습니다.

다른 팁

QT 5.3, serviceOwnerChanged 더 이상 사용되지 않습니다. 사용 QDBusServiceWatcher 이를 통해 모든 대신 특정 서비스를 볼 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top