D-BUS Adaptor ExampleThe following example code shows how a D-BUS interface can be implemented using an adaptor. A sample usage of QDBusAbstractAdaptor is as follows: class MainApplicationAdaptor: public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "com.example.DBus.MainApplication")
Q_CLASSINFO("D-Bus Interface", "org.kde.DBus.MainApplication")
Q_PROPERTY(QString caption READ caption WRITE setCaption)
Q_PROPERTY(QString organizationName READ organizationName)
Q_PROPERTY(QString organizationDomain READ organizationDomain)
private:
QApplication *app;
public:
MyInterfaceAdaptor(QApplication *application)
: QDBusAbstractAdaptor(application), app(application)
{
connect(application, SIGNAL(aboutToQuit()), SIGNAL(aboutToQuit());
connect(application, SIGNAL(focusChanged(QWidget*, QWidget*)),
SLOT(focusChangedSlot(QWidget*, QWidget*)));
}
QString caption()
{
if (app->hasMainWindow())
return app->mainWindow()->caption();
return QString(""); // must not return a null QString
}
void setCaption(const QString &newCaption)
{
if (app->hasMainWindow())
app->mainWindow()->setCaption(newCaption);
}
QString organizationName()
{
return app->organizationName();
}
QString organizationDomain()
{
return app->organizationDomain();
}
public slots:
Q_NOREPLY void quit()
{ app->quit(); }
void reparseConfiguration()
{ app->reparseConfiguration(); }
QString mainWindowObject()
{
if (app->hasMainWindow())
return QString("/%1/mainwindow").arg(app->applicationName());
return QString();
}
void setSessionManagement(bool enable)
{
if (enable)
app->enableSessionManagement();
else
app->disableSessionManagement();
}
private slots:
void focusChangedSlot(QWidget *, QWidget *now)
{
if (now == app->mainWindow())
emit mainWindowHasFocus();
}
signals:
void aboutToQuit();
void mainWindowHasFocus();
};
The code above would create an interface that could be represented more or less in the following canonical representation: interface com.example.DBus.MainApplication { property readwrite STRING caption property read STRING organizationName property read STRING organizationDomain method quit() annotation("org.freedesktop.DBus.Method.NoReply", "true") method reparseConfiguration() method mainWindowObject(out STRING) method disableSessionManagement(in BOOLEAN enable) signal aboutToQuit() signal mainWindowHasFocus() } interface org.kde.DBus.MainApplication { .... } This adaptor could be used in the application's main function as follows int main(int argc, char **argv) { // create the QApplication object QApplication app(argc, argv); // create the MainApplication adaptor: new MainApplicationAdaptor(app); // connect to D-BUS and register as an object: QDBus::sessionBus().registerObject("/MainApplication", app); // add main window, etc. [...] app.exec(); } Break-down analysis: The headerThe header of the example is: class MainApplicationAdaptor: public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.example.DBus.MainApplication") Q_CLASSINFO("D-Bus Interface", "org.kde.DBus.MainApplication") The code does the following:
The propertiesThe properties are declared as follows: Q_PROPERTY(QString caption READ caption WRITE setCaption) Q_PROPERTY(QString organizationName READ organizationName) Q_PROPERTY(QString organizationDomain READ organizationDomain) And are implemented as follows: QString caption() { if (app->hasMainWindow()) return app->mainWindow()->caption(); return QString(); } void setCaption(const QString &newCaption) { if (app->hasMainWindow()) app->mainWindow()->setCaption(newCaption); } QString organizationName() { return app->organizationName(); } QString organizationDomain() { return app->organizationDomain(); } The code declares three properties: one of them is a read-write property called "caption" of string type. The other two are read-only, also of the string type. The properties organizationName and organizationDomain are simple relays of the app object's organizationName and organizationDomain properties. However, the caption property requires verifying if the application has a main window associated with it: if there isn't any, the caption property is empty. Note how it is possible to access data defined in other objects through the getter/setter functions. The constructorThe constructor: MyInterfaceAdaptor(QApplication *application) : QDBusAbstractAdaptor(application), app(application) { connect(application, SIGNAL(aboutToQuit()), SIGNAL(aboutToQuit()); connect(application, SIGNAL(focusChanged(QWidget*, QWidget*)), SLOT(focusChangedSlot(QWidget*, QWidget*))); } The constructor does the following:
Note that there is no destructor in the example. An eventual destructor could be used to emit one last signal before the object is destroyed, for instance. Slots/methodsThe public slots in the example (which will be exported as D-BUS methods) are the following: public slots: Q_NOREPLY void quit() { app->quit(); } void reparseConfiguration() { app->reparseConfiguration(); } QString mainWindowObject() { if (app->hasMainWindow()) return QString("/%1/mainwindow").arg(app->applicationName()); return QString(); } void setSessionManagement(bool enable) { if (enable) app->enableSessionManagement(); else app->disableSessionManagement(); } This snippet of code defines 4 methods with different properties each:
See also: Q_NOREPLY. SignalsThe signals in this example are defined as follows: signals: void aboutToQuit(); void mainWindowHasFocus(); However, signal definition isn't enough: signals have to be emitted. One simple way of emitting signals is to connect another signal to them, so that Qt's signal handling system chains them automatically. This is what is done for the aboutToQuit signal. When this is the case, one can use the QDBusAbstractAdaptor::setAutoRelaySignals to automatically connect every signal from the real object to the adaptor. When simple signal-to-signal connection isn't enough, one can use a private slot do do some work. This is what was done for the mainWindowHasFocus signal: private slots: void focusChangedSlot(QWidget *, QWidget *now) { if (now == app->mainWindow()) emit mainWindowHasFocus(); } This private slot (which will not be exported as a method via D-BUS) was connected to the focusChanged signal in the adaptor's constructor. It is therefore able to shape the application's signal into what the interface expects it to be. |
Publicité
Best OfActualités les plus luesSemaine
Mois
Année
Le blog Digia au hasardCréer des applications avec un style Metro avec Qt, exemples en QML et C++, un article de Digia Qt traduit par Thibaut CuvelierLe blog Digia est l'endroit privilégié pour la communication sur l'édition commerciale de Qt, où des réponses publiques sont apportées aux questions les plus posées au support. Lire l'article.
CommunautéRessources
Liens utilesContact
Qt dans le magazine |
Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. | Qt 4.2 | |
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD. | ||
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP ! |
Copyright © 2000-2012 - www.developpez.com