Documentation/Maemo 5 Developer Guide/Development Environment/Maemo Programming Environments/Using Maemo 5 specific APIs in Qt application

(Using Zoom In and Zoom Out keys)
m (add Qt syntax highlighting)
 
(4 intermediate revisions not shown)
Line 5: Line 5:
=== Introduction ===
=== Introduction ===
-
This section explains how to use the [[Accelerometers | accelerometer]] D-Bus interface in a Maemo 5 Qt application.
+
This section explains how to use the [[N900 accelerometer|accelerometer]] D-Bus interface in a Maemo 5 Qt application.
The following code examples are used in this section:
The following code examples are used in this section:
-
* [https://garage.maemo.org/svn/maemoexamples/trunk/qt-maemo-gravity-example/ qt-maemo-gravity-example]
+
* [https://vcs.maemo.org/svn/maemoexamples/tags/maemo_5.0/qt-maemo-gravity-example/ qt-maemo-gravity-example]
=== D-Bus interface ===
=== D-Bus interface ===
-
It is up to each application how to organize interactions with the [http://maemo.org/api_refs/5.0/beta/mce-dev/ MCE] orientation interface. In [[Documentation/Maemo 5 Developer Guide/Porting Software/Porting Existing GTK+ Application to Maemo 5#Portrait Mode | some cases]] catching orientation signal can be enough, but if, e.g., more frequent updates are needed, you might want to use method calls, as demonstrated in our example.
+
It is up to each application how to organize interactions with the [http://maemo.org/api_refs/5.0/beta/mce-dev/ MCE] orientation interface. In [[Documentation/Maemo 5 Developer Guide/Porting Software/Porting Existing GTK+ Application to Maemo 5#Portrait Mode|some cases]] catching orientation signal can be enough, but if more frequent updates are needed, for example, you might want to use method calls, as demonstrated in our example.
-
We've moved D-Bus related functionality and orientation based calculations to a separate library that implements `DeviceOrientationNotifier' class.  
+
We've moved D-Bus related functionality and orientation based calculations to a separate library that implements <code>DeviceOrientationNotifier</code> class.  
Our notifier asks MCE about orientation parameters with a certain period,  
Our notifier asks MCE about orientation parameters with a certain period,  
-
void DeviceOrientationNotifier::timerEvent(QTimerEvent *)
+
<source lang="cpp-qt">
-
{
+
void DeviceOrientationNotifier::timerEvent(QTimerEvent *)
-
  QDBusMessage msg = QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH, MCE_REQUEST_IF, MCE_DEVICE_ORIENTATION_GET);
+
{
-
  bool sent = QDBusConnection::systemBus().callWithCallback(msg, this, SLOT(mceOrientationSlot(QString, QString, QString, int, int, int)));
+
  QDBusMessage msg = QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH, MCE_REQUEST_IF, MCE_DEVICE_ORIENTATION_GET);
-
}
+
  bool sent = QDBusConnection::systemBus().callWithCallback(msg, this, SLOT(mceOrientationSlot(QString, QString, QString, int, int, int)));
-
processes answers in `mceOrientationSlot', and emits data needed by the application with the following signal.
+
}
-
void deviceOrientation(qreal pitch, qreal roll);
+
</source>
 +
processes answers in `mceOrientationSlot', and emits data needed by the application with the following signal:
 +
<source lang="cpp-qt">
 +
void deviceOrientation(qreal pitch, qreal roll);
 +
</source>
=== Example application ===
=== Example application ===
Line 27: Line 31:
We've modified [http://qt.nokia.com/doc/4.5/graphicsview-collidingmice.html one of Qt4 Examples] in order to show how device orientation can be used.
We've modified [http://qt.nokia.com/doc/4.5/graphicsview-collidingmice.html one of Qt4 Examples] in order to show how device orientation can be used.
In our case pitch and roll are scene's characteristics, so we've implemented a `SceneTuner', whose slot can be connected to an appropriate signal in order to setup these scene properties.
In our case pitch and roll are scene's characteristics, so we've implemented a `SceneTuner', whose slot can be connected to an appropriate signal in order to setup these scene properties.
-
DeviceOrientationNotifier notifier(100);
+
<source lang="cpp-qt">
-
SceneTuner tuner(&scene, TimerInterval);
+
DeviceOrientationNotifier notifier(100);
-
QObject::connect(&notifier, SIGNAL(deviceOrientation(qreal, qreal)), &tuner, SLOT(setProps(qreal, qreal)));
+
SceneTuner tuner(&scene, TimerInterval);
 +
QObject::connect(&notifier, SIGNAL(deviceOrientation(qreal, qreal)), &tuner, SLOT(setProps(qreal, qreal)));
 +
</source>
Based on that each mouse can take into account the gravity effect, see `Mouse::advance' for details.
Based on that each mouse can take into account the gravity effect, see `Mouse::advance' for details.
Line 39: Line 45:
hardkeyhandler.cpp:
hardkeyhandler.cpp:
-
void HardkeyHandler::grabIncreaseDecreaseKeys(QWidget* window, bool grab)
+
<source lang="cpp-qt">
-
{
+
void HardkeyHandler::grabIncreaseDecreaseKeys(QWidget* window, bool grab)
-
    // Tell maemo-status-volume to grab/ungrab increase/decrease keys
+
{
-
    unsigned long val = (grab==true)?1:0;
+
    // Tell maemo-status-volume to grab/ungrab increase/decrease keys
-
    Atom atom;
+
    unsigned long val = (grab==true)?1:0;
-
    atom = XInternAtom( QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", 0);
+
    Atom atom;
-
    XChangeProperty (QX11Info::display(),
+
    atom = XInternAtom( QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", 0);
-
                      window->winId(),
+
    XChangeProperty (QX11Info::display(),
-
                      atom,
+
                    window->winId(),
-
                      XA_INTEGER,
+
                    atom,
-
                      32,
+
                    XA_INTEGER,
-
                      PropModeReplace,
+
                    32,
-
                      (unsigned char *) &val,
+
                    PropModeReplace,
-
                      1);
+
                    (unsigned char *) &val,
-
}
+
                    1);
 +
}
 +
</source>
Next, a handler for keypresses is created. 73 and 74 are the keycodes for F7/F8 in the SDK and Zoom In/Out buttons in the device. Handler functions emit corresponding signals when called.
Next, a handler for keypresses is created. 73 and 74 are the keycodes for F7/F8 in the SDK and Zoom In/Out buttons in the device. Handler functions emit corresponding signals when called.
-
hardkeyhandler.cpp
+
hardkeyhandler.cpp:
-
bool HardkeyHandler::processX11Event(XEvent* event)
+
<source lang="cpp-qt">
-
{
+
bool HardkeyHandler::processX11Event(XEvent* event)
-
    if ( event->type == KeyPress )
+
{
-
    {
+
    if ( event->type == KeyPress )
-
        if (event->xkey.keycode == 73 || event->xkey.keycode == QKeySequence::ZoomOut)
+
    {
-
        {
+
        if (event->xkey.keycode == 73 || event->xkey.keycode == QKeySequence::ZoomOut)
-
            emit decreaseKeyPressed();
+
        {
-
            return true;
+
            emit decreaseKeyPressed();
-
        }  
+
            return true;
-
        else if (event->xkey.keycode == 74  || event->xkey.keycode ==  QKeySequence::ZoomIn)
+
        }  
-
        {
+
        else if (event->xkey.keycode == 74  || event->xkey.keycode ==  QKeySequence::ZoomIn)
-
            emit increaseKeyPressed();
+
        {
-
            return true;
+
            emit increaseKeyPressed();
-
        }
+
            return true;
-
    }
+
        }
-
+
    }
-
    return false;
+
-
}
+
 +
    return false;
 +
}
 +
</source>
-
Signals need slots, of course. They are located to myapplication.h and myapplication.cpp files. Here changing to fullscreen and back are done by <code>showFullScreen()</code> and <code>showNormal()</code>.
+
Signals need slots, of course. They are located in <code>myapplication.h</code> and <code>myapplication.cpp</code> files. Here changing to fullscreen and back are done by <code>showFullScreen()</code> and <code>showNormal()</code>.
-
myapplication.cpp
+
myapplication.cpp:
-
void MyApplication::increaseKeyPressed()
+
<source lang="cpp-qt">
-
{
+
void MyApplication::increaseKeyPressed()
-
    qDebug("MyApplication::increaseKeyPressed");
+
{
-
    view.showFullScreen();
+
    qDebug("MyApplication::increaseKeyPressed");
-
+
    view.showFullScreen();
-
}
+
-
+
-
void MyApplication::decreaseKeyPressed()
+
-
{
+
-
    qDebug("MyApplication::decreaseKeyPressed");
+
-
    view.showNormal();
+
-
}
+
 +
}
 +
 +
void MyApplication::decreaseKeyPressed()
 +
{
 +
    qDebug("MyApplication::decreaseKeyPressed");
 +
    view.showNormal();
 +
}
 +
</source>
The new signals are connected to corresponding slots in <code>main()</code>.
The new signals are connected to corresponding slots in <code>main()</code>.
-
main.cpp
+
main.cpp:
-
QObject::connect(app.keyHandler(), SIGNAL(decreaseKeyPressed()), &app, SLOT(decreaseKeyPressed()));
+
<source lang="cpp-qt">
-
QObject::connect(app.keyHandler(), SIGNAL(increaseKeyPressed()), &app, SLOT(increaseKeyPressed()));
+
QObject::connect(app.keyHandler(), SIGNAL(decreaseKeyPressed()), &app, SLOT(decreaseKeyPressed()));
 +
QObject::connect(app.keyHandler(), SIGNAL(increaseKeyPressed()), &app, SLOT(increaseKeyPressed()));
 +
</source>
-
Finally, gtk-x11 library and the new source and header files (hardkeyhandler.* and myapplication.*) are added to the Qt project file:
+
Finally, <code>gtk-x11</code> library and the new source and header files (hardkeyhandler.* and myapplication.*) are added to the Qt project file:
collidingmice-gravity.pro:
collidingmice-gravity.pro:
-
LIBS += -ldevornot-qt-maemo -L/usr/local/lib -lgtk-x11-2.0
+
<pre>
-
+
LIBS += -ldevornot-qt-maemo -L/usr/local/lib -lgtk-x11-2.0
-
HEADERS += \
+
 
-
    mouse.h \
+
HEADERS += \
-
    hardkeyhandler.h \
+
    mouse.h \
-
    myapplication.h \
+
    hardkeyhandler.h \
-
    scenetuner.h
+
    myapplication.h \
-
SOURCES += \
+
    scenetuner.h
-
    main.cpp \
+
SOURCES += \
-
    hardkeyhandler.cpp \
+
    main.cpp \
-
    myapplication.cpp \
+
    hardkeyhandler.cpp \
-
    mouse.cpp
+
    myapplication.cpp \
 +
    mouse.cpp
 +
</pre>
 +
 
 +
[[Category:Development]]
 +
[[Category:Documentation]]
 +
[[Category:Fremantle]]

Latest revision as of 12:02, 9 March 2011

Contents

[edit] How to use Maemo 5 specific APIs from Qt application

[edit] Accelometer

[edit] Introduction

This section explains how to use the accelerometer D-Bus interface in a Maemo 5 Qt application.

The following code examples are used in this section:

[edit] D-Bus interface

It is up to each application how to organize interactions with the MCE orientation interface. In some cases catching orientation signal can be enough, but if more frequent updates are needed, for example, you might want to use method calls, as demonstrated in our example. We've moved D-Bus related functionality and orientation based calculations to a separate library that implements DeviceOrientationNotifier class. Our notifier asks MCE about orientation parameters with a certain period,

void DeviceOrientationNotifier::timerEvent(QTimerEvent *)
{
  QDBusMessage msg = QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH, MCE_REQUEST_IF, MCE_DEVICE_ORIENTATION_GET);
  bool sent = QDBusConnection::systemBus().callWithCallback(msg, this, SLOT(mceOrientationSlot(QString, QString, QString, int, int, int)));
}

processes answers in `mceOrientationSlot', and emits data needed by the application with the following signal:

void deviceOrientation(qreal pitch, qreal roll);

[edit] Example application

We've modified one of Qt4 Examples in order to show how device orientation can be used. In our case pitch and roll are scene's characteristics, so we've implemented a `SceneTuner', whose slot can be connected to an appropriate signal in order to setup these scene properties.

DeviceOrientationNotifier notifier(100);
SceneTuner tuner(&scene, TimerInterval);
QObject::connect(&notifier, SIGNAL(deviceOrientation(qreal, qreal)), &tuner, SLOT(setProps(qreal, qreal)));

Based on that each mouse can take into account the gravity effect, see `Mouse::advance' for details.

[edit] Using Zoom In and Zoom Out keys

This section uses the same qt-maemo-gravity-example to explain how to use Zoom In and Out keys in a Qt application. They are used to set the application window to fullscreen and normal modes like in the GTK+ example Maemo Sliders.

First, the keys are released from maemo-status-volume by using XChangeProperty().

hardkeyhandler.cpp:

void HardkeyHandler::grabIncreaseDecreaseKeys(QWidget* window, bool grab)
{
    // Tell maemo-status-volume to grab/ungrab increase/decrease keys
    unsigned long val = (grab==true)?1:0;
    Atom atom;
    atom = XInternAtom( QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", 0);
    XChangeProperty (QX11Info::display(),
                     window->winId(),
                     atom,
                     XA_INTEGER,
                     32,
                     PropModeReplace,
                     (unsigned char *) &val,
                     1);
}

Next, a handler for keypresses is created. 73 and 74 are the keycodes for F7/F8 in the SDK and Zoom In/Out buttons in the device. Handler functions emit corresponding signals when called.

hardkeyhandler.cpp:

bool HardkeyHandler::processX11Event(XEvent* event)
{
    if ( event->type == KeyPress )
    {
        if (event->xkey.keycode == 73 || event->xkey.keycode == QKeySequence::ZoomOut)
        {
            emit decreaseKeyPressed();
            return true;
        } 
        else if (event->xkey.keycode == 74  || event->xkey.keycode ==  QKeySequence::ZoomIn)
        {
            emit increaseKeyPressed();
            return true;
        }
    }
 
    return false;
}

Signals need slots, of course. They are located in myapplication.h and myapplication.cpp files. Here changing to fullscreen and back are done by showFullScreen() and showNormal().

myapplication.cpp:

void MyApplication::increaseKeyPressed()
{
    qDebug("MyApplication::increaseKeyPressed");
    view.showFullScreen();
 
}
 
void MyApplication::decreaseKeyPressed()
{
    qDebug("MyApplication::decreaseKeyPressed");
    view.showNormal();
}

The new signals are connected to corresponding slots in main().

main.cpp:

QObject::connect(app.keyHandler(), SIGNAL(decreaseKeyPressed()), &app, SLOT(decreaseKeyPressed()));
QObject::connect(app.keyHandler(), SIGNAL(increaseKeyPressed()), &app, SLOT(increaseKeyPressed()));

Finally, gtk-x11 library and the new source and header files (hardkeyhandler.* and myapplication.*) are added to the Qt project file:

collidingmice-gravity.pro:

LIBS += -ldevornot-qt-maemo -L/usr/local/lib -lgtk-x11-2.0

HEADERS += \
    mouse.h \
    hardkeyhandler.h \
    myapplication.h \
    scenetuner.h
SOURCES += \
    main.cpp \
    hardkeyhandler.cpp \
    myapplication.cpp \
    mouse.cpp