Post on 25-Jul-2015
Integrazione
QML / C++
Paolo Sereno
Chi Sono ?
…un informatico
Seguo l’evoluzione del Qt Application Framework dal
lontano 2003
Nell’ottobre 2009 ho fondato la web community
www.qt-italia.org (chi vuol collaborare… serve aiuto!)
Qt day 2015 2
Dove va il mondo?
Qt day 2015 3
prototipazione (sempre più) rapida
interaction design
user experience
Internet of things
Sempre più velocemente…
E quindi ?
Qt day 2015 4
…ma da solo non basta…
In diverse occasioni si rende necessario estendere
QML con C++
Qt day 2015 5
Fonte: Qt Assistant 5.4
QML è stato progettato per essere esteso mediante C++
Le funzionalità C++ possono essere invocate da QML
Gli oggetti QML possono essere caricati e modificati da
C++
Qt day 2015 6
Esportare oggetti C++ verso QML
Esportare oggetti C++ a QML
Qt day 2015 8
The QQmlContext class defines a context within a QML engine.
proviamo a capire…
Esportare oggetti C++ a QML
The QQmlContext class defines a context within a QML engine.
#include <QApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
Qt day 2015 9
Esportare oggetti C++ a QML
#include <QQmlContext>
#include "label.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
QQmlContext *context=engine.rootContext();
Label label("Pippo");
context->setContextProperty("label",&label);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
Qt day 2015 10
The QQmlContext class defines a
context within a QML engine.
label.h
class Label : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
explicit Label(QString name, QObject *parent = 0);
~Label();
QString name(){return m_name;};
void setName(QString newName){m_name=newName; emit nameChanged();};
signals:
void nameChanged();
public slots:
private:
QString m_name;
Qt day 2015 11
label.cpp
#include "label.h“
Label::Label(QString name, QObject *parent) : QObject(parent)
{
setName(name);
}
Label::~Label()
{
}
Qt day 2015 12
MainForm.ui.qml
Item {
width: 320
height: 240
property alias button1: button1
RowLayout {
anchors.centerIn: parent
Button {
id: button1
text: label.name
}
}
}
Qt day 2015 13
context->setContextProperty("label",&label);
Q_PROPERTY(QString name READ name WRITE setName
NOTIFY nameChanged)
main.qml
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
ApplicationWindow {
title: qsTr("Hello World")
width: 320
height: 240
visible: true
MainForm {
anchors.fill: parent
button1.onClicked:label.name="Paperino";
}
}
Qt day 2015 14
context->setContextProperty("label",&label);
Q_PROPERTY(QString name READ name WRITE setName
NOTIFY nameChanged)
Risultato
prima
Qt day 2015 15
Risultato
dopo
Qt day 2015 16
Esportare classi C++ verso QML
Classi «NON GUI»
Esportare classi a QML
Types can be registered by calling qmlRegisterType() with an
appropriate type namespace and version number.
proviamo a capire…
Qt day 2015 18
Esportare classi a QML
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "label.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
qmlRegisterType <Label>("com.helloworld.qmlcomponents",1,0,"Label");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
Qt day 2015 19
MainForm.ui.qml
import com.helloworld.qmlcomponents 1.0
Item {
width: 320
height: 240
property alias button1: button1
property alias label:label
Label {
id:label
name: "Pluto"
}
Qt day 2015 20
main.qml
…
MainForm {
anchors.fill: parent
button1.onClicked: {
label.name="Paperino"
button1.text=label
}
}
Qt day 2015 21
Risultato
prima
Qt day 2015 22
Risultato
dopo
Qt day 2015 23
E se facessi così ?
Item {
width: 320
height: 240
property alias button1: button1
//property alias label:label
Label {
id:label
name: "Pluto"
}
Qt day 2015 24
Questo il risultato…
Qt day 2015 25
Esportare classi C++ verso QML
Classi «GUI»
Esportare classi (GUI) a QML
The QQuickPaintedItem class provides a way to use the QPainter API
in the QML Scene Graph.
proviamo a capire…
Qt day 2015 27
main.cpp
#include "rettangolo.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType <Rettangolo>("com.helloworld.qmlcomponents",1,0,"Rettangolo");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
Qt day 2015 28
rettangolo.h
#include <QQuickPaintedItem>
#include <QPainter>
class Rettangolo : public QQuickPaintedItem
{
Q_OBJECT
public:
explicit Rettangolo(QQuickItem *parent = 0);
void paint(QPainter *painter);
signals:
public slots:
};
Qt day 2015 29
rettangolo.cpp
void Rettangolo::paint(QPainter *painter)
{
QLinearGradient linearGrad(QPointF(0,0), QPointF(0,height()));
linearGrad.setColorAt(0, QColor(90,180,90,255));
linearGrad.setColorAt(1, QColor(10,120,10,255));
QBrush brush=QBrush(linearGrad);
painter->fillRect(boundingRect(),brush);
}
Qt day 2015 30
MainForm.ui.qml
Item {
width: 320
height: 240
RowLayout {
anchors.centerIn: parent
Rettangolo {
id: rect;
width: 100
height: 100
}
}
}
Qt day 2015 31
Risultato
Qt day 2015 32
Model View Delegate
C++/QML
Model-View-Delegate
Qt day 2015 34
StringListModelclass StringListModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit StringListModel (QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &value, int role =
Qt::EditRole);
bool insertRows(int position, int rows, const QModelIndex &parent);
bool removeRows(int position, int rows, const QModelIndex &parent);
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
private:
QStringList mItemsList;
Qt day 2015 35
stringlistmodel.cpp
StringListModel::StringListModel(QObject *parent)
:QAbstractListModel(parent)
{
mItemsList <<"Pippo"<<"Pluto"<<"Paperino";
}
Qt day 2015 36
stringlistmodel.cpp
QVariant StringListModel::data(const QModelIndex &index, int role)
const
{
if(index.isValid() && index.row() < this->mItemsList.size() &&
role == Qt::DisplayRole)
return this->mItemsList.at(index.row());
return QVariant();
}
Qt day 2015 37
main.cpp
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<StringListModel>("com.helloworld.Models", 1, 0,
"StringListModel");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
Qt day 2015 38
MainForm.ui.qml
StringListModel{
id:myModel
}
ListView {
id: listView
model: myModel
delegate: Item {
Row {
id: row1
Text {
text: display
}
}
Qt day 2015 39
Risultato
Qt day 2015 40
Q_INVOKABLE
class StringListModel : public QAbstractListModel
{
Q_OBJECT
public:
…
Q_INVOKABLE QString getSomething ();
private:
QStringList mItemsList;
QString mSomething;
}
Qt day 2015 41
getSomething()
QString StringListModel::getSomething()
{
return mSomething;
}
Qt day 2015 42
stringlistmodel.cpp
StringListModel::StringListModel(QObject *parent)
:QAbstractListModel(parent)
{
mItemsList <<"Pippo"<<"Pluto"<<"Paperino";
mSomething="La mia lista";
}
Qt day 2015 43
Uso di getSomething
Text {
id: text1
x: 105
y: 20
width: 110
height: 24
text: myModel.getSomething()
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 12
}
Qt day 2015 44
Risultato
Qt day 2015 45
Esportare oggetti QML verso C++
main.qml
ApplicationWindow {
…
Button {
x:110
y:80
objectName: "button1"
width:100
height:40
text: "QML"
}
}
Qt day 2015 47
main.cpp
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/main.qml")));
QObject *object = component.create();
QObject *button = object->findChild<QObject *>("button1");
if(button)
button->setProperty("text","c++");
return app.exec();
}
Qt day 2015 48
Risultato
Qt day 2015 49
Qt day 2015 50
E’ quasi finito!
…lo troverete su AmazonQt day 2015 51
DOMANDE ???