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  · 

Qt Extended IPC Layer

Introduction

Qtopia 4.2 introduced a new inter-process communication (IPC) API aimed to make it extremely easy to send and receive messages between applications. It is designed to be used in several ways, and features an intelligent data serialization infrastructure based on the Qt meta-type system. This enables the user to easily send messages across applications that can contain custom types. The user only has to implement serialization and deserialization functions and register the custom type with the API.

The Qt Extended IPC API is based on the notion of channels and messages. Messages can be used by by an application to notify another application to take some action. Messages can have arguments associated with them. In essence, a message can be thought of as a remote method call. A message consists of a function identifier followed by a list of types in parantheses. There is no whitespace in the message name.

Channels are unique string based identifiers which are used to logically group a set of messages together. Effectively, a set of messages on a particular channel defines an interface. By convention all channels within Qt Extended start with "QPE/".

The Qt Extended IPC system uses the event-processing loop. If you create a message it will not be sent until the next the event loop is entered.

Qt Extended IPC system consists of three major classes. The QtopiaIpcAdaptor is the preferred way to interface with the system. In addition, QtopiaChannel and QtopiaIpcEnvelope classes are provided to ease the transition between the Qt Extended QCopChannel based systems and the new API.

QtopiaIpcAdaptor

Overview

Qt Extended IPC API is exposed to the user through the QtopiaIpcAdaptor class. QtopiaIpcAdaptor can be used in two ways: direct access and an inheritance based approach.

To use QtopiaIpcAdaptor directly, we first construct a new object by providing a channel as so:

    QtopiaIpcAdaptor *adaptor = new QtopiaIpcAdaptor("QPE/CannonExample");

The newly created adaptor object can now be used to send messages to remote applications, or to receive messages. To send messages use the send method calls:

    // First we aim the cannon
    QtopiaIpcSendEnvelope envelope = adaptor->send(MESSAGE(aimCannon(int,int)));
    envelope << direction << elevation;

    // Alternatively if there are less than 3 arguments we can use send directly
    adaptor->send(MESSAGE(shootCannon(int)), cannonPower);

Another application is responsible for actually aiming and shooting the cannon. Let us suppose that the cannon application can reply with two types of messages, a hit or a miss. E.g. the remote application will send a missed() or hit() message. We can listen for such messages in the following manner:

    class CannonListener : public QObject
    {
        Q_OBJECT

    public slots:
        void missed();
        void hit();
    };

    ...

    CannonListener *listener = new CannonListener;
    QtopiaIpcAdaptor *adaptor = new QtopiaIpcAdaptor("QPE/CannonExample");
    QtopiaIpcAdaptor::connect(adaptor, MESSAGE(missed()), listener, SLOT(missed()));
    QtopiaIpcAdaptor::connect(adaptor, MESSAGE(hit()), listener, SLOT(hit()));

We can also use QtopiaIpcAdaptor::connect to enable an object's signals to be sent over a channel automatically. For instance, we can rewrite the above example like this:

    class CannonController : public QObject
    {
        Q_OBJECT

    public slots:
        void missed();
        void hit();

    signals:
        void aimCannon(int dir, int elev);
        void shootCannon(int power);
    };

    ...

    CannonController *control = new CannonController;
    QtopiaIpcAdaptor *adaptor = new QtopiaIpcAdaptor("QPE/CannonExample");

    // Hookup remote messages to our object
    QtopiaIpcAdaptor::connect(adaptor, MESSAGE(missed()), control, SLOT(missed()));
    QtopiaIpcAdaptor::connect(adaptor, MESSAGE(hit()), control, SLOT(hit()));

    // Send our signals to the remote object
    QtopiaIpcAdaptor::connect(control, SIGNAL(aimCannon(int,int)), adaptor, MESSAGE(aimCannon(int,int)));
    QtopiaIpcAdaptor::connect(control, SIGNAL(shootCannon(int)), adaptor, MESSAGE(shootCannon(int)));

We should now recognize that for non-trivial interactions the last example is a quite common use case. It is thus desirable to avoid using QtopiaIpcAdaptor::connect for each connection, which can be quite error prone. QtopiaIpcAdaptor provides an alternate interaction technique based on inheritance. Instead of creating another class and using QtopiaIpcAdaptor::connect, we inherit directly from QtopiaIpcAdaptor and use the publish or publishAll methods to automatically publish all signals and slots on the channel. E.g.:

        class CannonController : public QtopiaIpcAdaptor
        {
            Q_OBJECT

        public:
            CannonController(QObject *parent = 0);
            void shoot();

        public slots:
            void missed();
            void hit();

        signals:
            void aimCannon(int dir, int elev);
            void shootCannon(int power);
        };

        CannonController::CannonController(QObject *parent)
            : QtopiaIpcAdaptor("QPE/CannonExample", parent)
        {
            publishAll(QtopiaIpcAdaptor::SignalsAndSlots);
        }

        void CannonController::missed()
        {
            qDebug() << "Cannon missed!";
        }

        void CannonController::hit()
        {
            qDebug() << "Cannon HIT!";
        }

        void CannonController::shoot()
        {
            emit aimCannon(0, 45);
            emit shootCannon(100);
        }

    ...

        CannonController *control = new CannonController;
        control->shoot();

Serialization System

Enumerations

To make the example complete, we show how to extend our example with custom data types. First let us suppose that we'd like to use a custom ammunition type. We define a new enumeration named appropriately AmmunitionType. In order to exchange these enumerations, we must first register it with the meta-type system. This is accomplished by using the Q_DECLARE_USER_METATYPE_ENUM macro. This macro must be used in the header file where the enumeration is defined. Additionally we must use the Q_IMPLEMENT_USER_METATYPE_ENUM macro to implement the necessary serialization and deserialization functions.

        // Header
        class CannonController : public QtopiaIpcAdaptor
        {
            Q_OBJECT

        public:
            enum AmmunitionType { Explosive = 0, ArmorPiercing, Napalm }

            CannonController(QObject *parent = 0);
            void shoot();

        public slots:
            void missed();
            void hit();

        signals:
            void aimCannon(int dir, int elev);
            void shootCannon(int power);
            void setAmmunitionType(AmmunitionType type);
        };

        Q_DECLARE_USER_METATYPE_ENUM(CannonController::AmmunitionType)

    ...

        // Implementation:

        Q_IMPLEMENT_USER_METATYPE_ENUM(CannonController::AmmunitionType)

Custom Classes

In order to shoot our cannon we now need to send three messages to the remote application. For such a complex and mission critical system we should really send only one message for efficiency purposes. We define a new class that encapsulates the entire shoot order:

        class CannonFireOrders
        {
        public:
            enum AmmunitionType { Explosive = 0, ArmorPiercing, Napalm }
            CannonFireOrders( AmmunitionType type, int direction, int elevation, int power);

            int direction() const;
            int elevation() const;
            int power() const;
            AmmunitionType type() const;

        private:
            int m_dir;
            int m_elev;
            int m_power;
            AmmunitionType m_type;
        };

        Q_DECLARE_USER_METATYPE_ENUM(CannonFireOrders::AmmunitionType)
        Q_DECLARE_USER_METATYPE(CannonFireOrders)

We also modify the CannonController class in the following manner:

        class CannonController : public QtopiaIpcAdaptor
        {
            Q_OBJECT

        public:
            CannonController(QObject *parent = 0);
            void shoot();

        public slots:
            void missed();
            void hit();

        signals:
            void shootCannon(const CannonFireOrders &orders);
        };

The only thing missing is a way to tell the Qt Extended IPC API how to serialize the CannonFireOrders class so it can be shipped to a remote applications, and how the other side would deserialize the information and create a CannonFireOrders. To accomplish this, we must define two new methods in the CannonFireOrders class:

        class CannonFireOrders
    {
        public:

        ....

        template <typename Stream> void serialize(Stream &stream) const;
        template <typename Stream> void deserialize(Stream &stream);
        ...
    };

And in the implementation file we implement both methods. It is important to note this fact, as usually templates are defined in the header files!

        Q_IMPLEMENT_USER_METATYPE_ENUM(CannonFireOrders::AmmunitionType)
        Q_IMPLEMENT_USER_METATYPE(CannonFireOrders)

        ....

        template <typename Stream> void CannonFireOrders::serialize(Stream &s) const
        {
            s << m_dir;
            s << m_elev;
            s << m_power;
            s << m_type;
        }

        template <typename Stream> void CannonFireOrders::deserialize(Stream &s)
        {
            s >> m_dir;
            s >> m_elev;
            s >> m_power;
            s >> m_type;
        }

We can now successfully use custom classes across applications! Please note that both applications must link in the implementation of the custom class.

Migrating Legacy Qt Extended Applications

Developers are encouraged to use the new QtopiaIpcAdapter API. It is extremely powerful and can easily support custom classes. However, to support legacy applications and make it easier to port such applications to the new IPC system, Qt Extended introduces two new classes. QtopiaChannel and QtopiaIpcEnvelope. Both of these classes work exactly as their QCop counterparts.

The Application Channel

Each application listens on a channel called QPE/Application/appname , where appname is the executable name (the application identifier). Standard messages on this channel are:

QPE/Application/appname

  • setDocument(QString) -- Internal. Causes the setDocument(const QString&) slot of the main document widget be called.
  • nextView() -- Applications connected to hardware buttons will receive this message if they are already visible.
  • raise() -- Internal. Causes the the main document widget and the current modal widget to be raised.
  • quit() -- Internal. Terminates the application.
  • quitIfInvisible() -- Internal. Terminates the application if it is not shown.

The QPE/Application/appname channel has a special property: when messages are sent to these channels via QtopiaIpcEnvelope, the message is delivered even if the application is not yet running (the application is run and the message is then sent).

Command-line access to Qt Extended IPC System

The qcop command-line tool can be used to access the Qt Extended IPC system from shell scripts and for debugging purposes.

Publicité

Best Of

Actualités les plus lues

Semaine
Mois
Année
  1. « Quelque chose ne va vraiment pas avec les développeurs "modernes" », un développeur à "l'ancienne" critique la multiplication des bibliothèques 53
  2. Les développeurs ignorent-ils trop les failles découvertes dans leur code ? Prenez-vous en compte les remarques des autres ? 17
  3. 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
  4. Apercevoir la troisième dimension ou l'utilisation multithreadée d'OpenGL dans Qt, un article des Qt Quarterly traduit par Guillaume Belz 0
  5. Quelles nouveautés de C++11 Visual C++ doit-il rapidement intégrer ? Donnez-nous votre avis 10
  6. Adieu qmake, bienvenue qbs : Qt Building Suite, un outil déclaratif et extensible pour la compilation de projets Qt 17
  7. La rubrique Qt a besoin de vous ! 1
Page suivante

Le blog Digia au hasard

Logo

Déploiement d'applications Qt Commercial sur les tablettes Windows 8

Le 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 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 qtextended4.4
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