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 !