I. Article original▲
Cet article est une adaptation en langue française de Screen orientation detection for QML.
II. Une classe Orientation▲
On écrit tout d'abord une classe Orientation qui utilise un QOrientationSensor pour détecter les changements d'orientation du périphérique.
En voici l'en-tête orientation.h :
class Orientation : public QObject
{
Q_OBJECT
Q_PROPERTY(QString state READ state NOTIFY orientationChanged)
public:
explicit Orientation(QObject *parent = 0);
~Orientation();
inline QString state() const { return m_state; }
signals:
void orientationChanged();
private slots:
void onReadingChanged();
private:
QString m_state;
QtMobility::QOrientationSensor* m_sensor;
};
On a utilisé la macro Q_PROPERTY() pour rendre la propriété d'état disponible depuis QML. NOTIFY orientationChanged est important,
puisque cette partie s'assure que QML sera notifié lors d'un changement d'orientation (c'est-à-dire quand le signal orientationChanged() est émis). L'utilisation de cette macro pour exposer des données depuis C++ à QML est expliqué dans la documentation.
L'implémentation est la suivante :
Orientation::Orientation(QObject *parent) :
QObject(parent), m_state("Portrait")
{
m_sensor = new QOrientationSensor(this);
connect(m_sensor, SIGNAL(readingChanged()), SLOT(onReadingChanged()));
m_sensor->start();
}
Orientation::~Orientation() {
delete m_sensor;
}
void Orientation::onReadingChanged()
{
QOrientationReading* reading = m_sensor->reading();
switch(reading->orientation())
{
case QOrientationReading::TopUp:
m_state = "Landscape";
emit orientationChanged();
break;
case QOrientationReading::TopDown:
m_state = "LandscapeInverted";
emit orientationChanged();
break;
case QOrientationReading::LeftUp:
m_state = "Portrait";
emit orientationChanged();
break;
case QOrientationReading::RightUp:
m_state = "PortraitInverted";
emit orientationChanged();
default:
break;
}
}III. Exposition à QML▲
Ensuite, on instancie cet objet et on l'expose à QML avec QDeclarativeContext::setContextProperty() :
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QDeclarativeView view;
view.setResizeMode(QDeclarativeView::SizeRootObjectToView);
const QRect screenGeometry = QApplication::desktop()->screenGeometry();
view.setGeometry(screenGeometry);
QDeclarativeContext *context = view.rootContext();
context->setContextProperty("screenWidth", screenGeometry.width());
context->setContextProperty("screenHeight", screenGeometry.height());
context->setContextProperty("Orientation", new Orientation(&app));
view.setSource(QUrl("qrc:/qml/ScreenOrientationQML/main.qml"));
view.showFullScreen();
return app.exec();
}Côté QML, on l'utilise comme ceci :
import Qt 4.7
Rectangle {
id: window
width: screenWidth
height: screenHeight
anchors.centerIn: parent
state: Orientation.state
Text {
anchors.fill: parent
text: "Hello World!"
}
states: [
State {
name: "Landscape"
PropertyChanges {
target: window
rotation: 0
width: screenWidth
height: screenHeight
x: 0
y: 0
}
},
State {
name: "LandscapeInverted"
PropertyChanges {
target: window
rotation: 180
width: screenWidth
height: screenHeight
x: 0
y: 0
}
},
State {
name: "Portrait"
PropertyChanges {
target: window
rotation: 270
width: screenHeight
height: screenWidth
x: (screenWidth - screenHeight) / 2
y: -(screenWidth - screenHeight) / 2
}
},
State {
name: "PortraitInverted"
PropertyChanges {
target: window
rotation: 90
width: screenHeight
height: screenWidth
x: (screenWidth - screenHeight) / 2
y: -(screenWidth - screenHeight) / 2
}
}
]
transitions: [
Transition {
from: "*"
to: "*"
ParallelAnimation {
RotationAnimation {
properties: "rotation"
duration: 250
direction: RotationAnimation.Shortest
}
PropertyAnimation {
target: window
properties: "x,y,width,height"
duration: 250
}
}
}
]
}Comme on peut le voir, on observe quatre états QML, un par orientation ; l'application se base sur la propriété d'état de l'objet Orientation pour déterminer lequel utiliser. On a aussi ajouté quelques animations de transition pour améliorer l'affichage.
IV. Remerciements▲
Merci à Guillaume Belz et Stoyak pour leur relecture attentive !







