Viadeo Twitter Google Bookmarks ! Facebook Digg del.icio.us MySpace Yahoo MyWeb Blinklist Netvouz Reddit Simpy StumbleUpon Bookmarks Windows Live Favorites 
Logo Documentation Qt ·  Page d'accueil  ·  Toutes les classes  ·  Toutes les fonctions  ·  Vues d'ensemble  · 

Service Browser Example

Files:

This example shows how to use the Service Framework to:

  • Register and unregister services
  • Find available services
  • Find the interfaces that are implemented by a service
  • Look up the attributes for an interface implementation using the meta-object system
  • Set a default interface implementation

Screenshot of the Service Browser example

The application window is split into three panes.

The top-left pane shows all the services that are registered within the Service Framework. For this example, the filemanagerplugin and bluetoothtransferplugin services included in the examples/ directory have been registered, and so are visible in this pane.

The bottom-left pane shows the interfaces implemented by the service selected in the top-left pane. Each entry in this list shows:

  • The name and version of the implemented interface
  • The service that provides this implementation (in brackets)
  • Whether the implementation is the default for its interface

The right-hand pane shows the attributes of an interface implementation that are invokable through the Qt meta-object system. Such attributes include signals, slots, properties and methods marked with the Q_INVOKABLE macro. If the "Selected implementation" radio button is checked, this view shows the attributes of the selected implementation in the bottom-left pane; otherwise, it shows the attributes of the default implementation for the interface of the selected implementation.

ServiceBrowser Class Definition

The ServiceBrowser class inherits from QWidget. It has several slots for reloading the lists in the three information panes, and for changing the default implementation for an interface.

 class ServiceBrowser : public QWidget
 {
     Q_OBJECT
 public:
     ServiceBrowser(QWidget *parent = 0, Qt::WindowFlags flags = 0);
     ~ServiceBrowser();

 private slots:
     void currentInterfaceImplChanged(QListWidgetItem *current, QListWidgetItem *previous);
     void reloadServicesList();
     void reloadInterfaceImplementationsList();
     void reloadAttributesList();
     void setDefaultInterfaceImplementation();

 private:
     ...
 };

ServiceBrowser Class Implementation

 ServiceBrowser::ServiceBrowser(QWidget *parent, Qt::WindowFlags flags)
     : QWidget(parent, flags)
 {
     serviceManager = new QServiceManager(this);
     systemManager = new QServiceManager(QService::SystemScope);

     registerExampleServices();

     initWidgets();
     reloadServicesList();

     setWindowTitle(tr("Services Browser"));
 }

The constructor registers the "FileManagerService", "BluetoothTransferService" and "NotesManagerServices" services that are provided by the filemanagerplugin and bluetoothtransferplugin projects in the examples/ directory. It also calls reloadServicesList() to show these two newly registered services in the top-left pane.

 void ServiceBrowser::reloadServicesList()
 {
     servicesListWidget->clear();

     QSet<QString> services;
     QList<QServiceInterfaceDescriptor> descriptors = serviceManager->findInterfaces();
     for (int i=0; i<descriptors.count(); i++) {
         QString service = descriptors[i].serviceName();

         if (descriptors[i].scope() == QService::SystemScope)
             service += tr(" (system)");

         services << service;
     }

When the services list in the top-left pane needs to be refreshed, we call QServiceManager::findServices() to get a QStringList of all services that are currently registered with the service framework.

 void ServiceBrowser::reloadInterfaceImplementationsList()
 {
     ...
     ...
     QList<QServiceInterfaceDescriptor> descriptors = manager->findInterfaces(serviceName);

     attributesListWidget->clear();
     interfacesListWidget->clear();
     for (int i=0; i<descriptors.count(); i++) {
         if (descriptors[i].scope() != manager->scope() && !serviceName.isEmpty())
             continue;

         QString text = QString("%1 %2.%3")
                 .arg(descriptors[i].interfaceName())
                 .arg(descriptors[i].majorVersion())
                 .arg(descriptors[i].minorVersion());

         QServiceInterfaceDescriptor defaultInterfaceImpl
             = manager->interfaceDefault(descriptors[i].interfaceName());

         if (serviceName.isEmpty()) {
             text += " (" + descriptors[i].serviceName() + ")";

             if (descriptors[i].scope() == QService::SystemScope) {
                 text += tr(" (system");
                 defaultInterfaceImpl = systemManager->interfaceDefault(descriptors[i].interfaceName());
                 if (descriptors[i] == defaultInterfaceImpl)
                     text += tr(" default)");
                 else
                     text += ")";
                 defaultInterfaceImpl = QServiceInterfaceDescriptor();
             }
     ...
         }

To create the list of interface implementations in the bottom-left pane, we call QServiceManager::findInterfaces() to get a list of QServiceInterfaceDescriptor objects. If a particular service has been selected in the top-left pane, we call QServiceManager::findInterfaces() with the name of that service as the argument, so that it will only return the interface implementations provided by that service. Otherwise, it is called with no argument to retrieve a list of all implementations provided by all registered services.

The example maps each entry in the interface implementations list to its corresponding QServiceInterfaceDescriptor object using the QListWidgetItem::setData() method.

Note how we also call QServiceManager::defaultServiceInterface() to determine whether an interface implementation is the default for that interface.

 void ServiceBrowser::reloadAttributesList()
 {
     QListWidgetItem *item = interfacesListWidget->currentItem();
     if (!item)
         return;

     QServiceInterfaceDescriptor selectedImpl =
             item->data(Qt::UserRole).value<QServiceInterfaceDescriptor>();

     QObject *implementationRef;
     if (selectedImplRadioButton->isChecked())
         implementationRef = serviceManager->loadInterface(selectedImpl, 0, 0);
     else
         implementationRef = serviceManager->loadInterface(selectedImpl.interfaceName(), 0, 0);

     ...

The reloadAttributesList() method creates the list in the right-hand pane that shows the attributes of an interface implementation that can be invoked through the Qt meta-object system.

QServiceManager::loadInterface() is called to get an instance of the identified interface implementation. This method finds the corresponding service plugin and returns the QObject instance provided by the service plugin's QServicePluginInterface::createInstance() method.

     ...
     const QMetaObject *metaObject = implementationRef->metaObject();
     attributesGroup->setTitle(tr("Invokable attributes for %1 class")
             .arg(QString(metaObject->className())));
     for (int i=0; i<metaObject->methodCount(); i++) {
         QMetaMethod method = metaObject->method(i);
         attributesListWidget->addItem("[METHOD] " + QString(method.signature()));
     }
     for (int i=0; i<metaObject->propertyCount(); i++) {
         QMetaProperty property = metaObject->property(i);
         attributesListWidget->addItem("[PROPERTY] " + QString(property.name()));
     }
 }

Call QObject::metaObject() on the implementation instance to get a QMetaObject instance that reveals the dynamically invokable attributes for the instance. These attributes include properties, signals, slots, and methods marked with the Q_INVOKABLE macro. Call QMetaObject::method() to get information about a signal, slot or invokable method, and QMetaObject::property() to access a property of the instance.

When you know the name of the method you wish to invoke, call QMetaObject::invoke() or QMetaMethod::invoke() to invoke it dynamically. Similarly, QMetaProperty::read() and QMetaProperty::write() can be used to read and modify the value of a property.

Invoking attributes: an example

Here is an example of invoking attributes on an implementation, using the FileManagerPlugin that is shown in the Service Browser.

The FileManagerPlugin provides a service called "FileManagerService" in its filemanagerplugin.xml service definition. When FileManagerPlugin::createInstance() is called, if the com.nokia.qt.examples.FileStorage interface is requested, it returns an instance of the FileManagerStorage class. The FileManagerStorage class is defined like this:

 class FileManagerStorage : public QObject
 {
     Q_OBJECT
     Q_PROPERTY(QString workingDirectory READ workingDirectory WRITE setWorkingDirectory)

 public:
     FileManagerStorage(QObject *parent = 0);

     void setWorkingDirectory(const QString &path);
     QString workingDirectory() const;

 signals:
     void workingDirectoryChanged(const QString &newDir);

 public slots:
     void copyFile(const QString &currentPath, const QString &newPath);

 private:
     QString directory;
 };

So if, in the ServiceBrowser application, we select the com.nokia.qt.examples.FileStorage implementation provided by FileManagerService, the browser would display all the dynamically invokable attributes of the FileManagerStorage class:

As you can see, the FileManagerStorage::workingDirectory property, the FileManagerStorage::copyFile() slot and the FileManagerStorage::workingDirectoryChanged() signal are all listed. (The destroyed(), deleteLater() and _q_reregisterTimers() attributes are inherited from the QObject parent.)

To invoke the copyFile() slot, for example:

 QObject *interfaceImpl = QServiceManager::loadInterface("com.nokia.qt.examples.FileStorage", 0, 0);
 QMetaObject::invokeMethod(interfaceImpl, "copyFile",
                           Q_ARG(QString, "path/to/file.txt"),
                           Q_ARG(QString, "new/path/to/file.txt"));

Of course, the QServiceManager::loadInterface() call here assumes the FileManagerStorage implementation is the default for the com.nokia.qt.examples.FileStorage interface. Otherwise, it would have to pass a QServiceInterfaceDescriptor object to QServiceManager::loadInterface() instead of just the interface name to ensure the correct implementation is loaded.

X

Thank you for giving your feedback.

Make sure it is related to this specific page. For more general bugs and requests, please use the Qt Bug Tracker.

[0]; s.parentNode.insertBefore(ga, s); })();
Publicité

Best Of

Actualités les plus lues

Semaine
Mois
Année
  1. Microsoft ouvre aux autres compilateurs C++ AMP, la spécification pour la conception d'applications parallèles C++ utilisant le GPU 22
  2. Les développeurs ignorent-ils trop les failles découvertes dans leur code ? Prenez-vous en compte les remarques des autres ? 17
  3. RIM : « 13 % des développeurs ont gagné plus de 100 000 $ sur l'AppWord », Qt et open-source au menu du BlackBerry DevCon Europe 0
  4. « Quelque chose ne va vraiment pas avec les développeurs "modernes" », un développeur à "l'ancienne" critique la multiplication des bibliothèques 12
  5. BlackBerry 10 : premières images du prochain OS de RIM qui devrait intégrer des widgets et des tuiles inspirées de Windows Phone 0
  6. Adieu qmake, bienvenue qbs : Qt Building Suite, un outil déclaratif et extensible pour la compilation de projets Qt 17
  7. Quelles nouveautés de C++11 Visual C++ doit-il rapidement intégrer ? Donnez-nous votre avis 10
Page suivante

Le Qt Developer Network au hasard

Logo

Applications mobiles modernes avec Qt et QML

Le Qt Developer Network est un réseau de développeurs Qt anglophone, où ils peuvent partager leur expérience sur le framework. Lire l'article.

Communauté

Ressources

Liens utiles

Contact

  • Vous souhaitez rejoindre la rédaction ou proposer un tutoriel, une traduction, une question... ? Postez dans le forum Contribuez ou contactez-nous par MP ou par email (voir en bas de page).

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 qtmobility-1.1
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 !
 
 
 
 
Partenaires

Hébergement Web