當(dāng)我們打算向qml中注冊自定義的C++類型時(shí),有幾個(gè)問題需要考慮:
1. 怎么將C++類型注冊到qml框架中熄阻,即怎么在qml文件中訪問該類型;
2. qml文件中怎么訪問自定義C++類型的屬性倔约;
3. qml文件中怎么訪問自定義C++類型的接口函數(shù)秃殉;
4. qml文件中怎么處理該自定義C++類型的信號。
向qml框架注冊自定C++類型:
注冊接口qmlRegisterType<CClassName>("PackageName", basVersion, subVersion, "QmlTypeName")
例如:
qmlRegisterType<PieChart>("Charts", 1, 0, "PieChart");
在qml中引用該類型:
import Charts 1.0
Item {
width: 300; height: 200
PieChart {
id: aPieChart
anchors.centerIn: parent
width: 100; height: 100
...
...
...
}
}
qml訪問自定義C++類型的屬性:
首先我們思考一個(gè)問題:是不是我們只需要將屬性定義為public類型,就可以直接在qml中訪問該類型的屬性了呢复濒?經(jīng)過測試脖卖,證明這樣不可行乒省!必須在C++代碼中注冊屬性巧颈,并實(shí)現(xiàn)其getter和setter接口:
Q_PROPERTY(QString propertyName READ getter WRITE setter)
代碼如下:
class PieChart : public QObject
{
Q_OBJECT
//Q_PROPERTY宏申明的屬性,可以在qml中使用袖扛,還可以用NOTIFY申明信號
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(QColor color READ color WRITE setColor)
public:
PieChart(QQuickItem *parent = 0);
QString name() const;
void setName(const QString &name);
QColor color() const;
void setColor(const QColor &color);
private:
QString m_name;
QColor m_color;
};
這樣就可以在qml中訪問其name和color屬性了砸泛,其值的讀取和設(shè)置分別由
QString name() const;
void setName(const QString &name);
和
QColor color() const;
void setColor(const QColor &color);提供;
但是有一點(diǎn)需要注意蛆封,此時(shí)還只能做簡單的屬性訪問和設(shè)置唇礁,但是不能再qml中對該屬性做動態(tài)綁定,因?yàn)閝ml框架無法感知屬性的變化惨篱,自然無法處理該屬性的動態(tài)綁定問題盏筐,那如何能讓qml框架感知屬性變化,從而實(shí)現(xiàn)動態(tài)綁定的效果呢砸讳?很顯然這要用到Qt的信號槽機(jī)制琢融,同樣還是需要用到Q_PROPERTY來處理:
Q_PROPERTY(QString propertyName READ getter WRITE setter NOTITY propertyChanged)
代碼如下:
class PieChart : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName)
//! NOTIFY申明信號,通知qml監(jiān)聽屬性變化簿寂,可以讓qml框架感知屬性變化漾抬,自動實(shí)現(xiàn)數(shù)據(jù)綁定效果
//! 否則需要自己處理信號,處理每一處的綁定數(shù)據(jù)的更新3K臁D闪睢!克胳!
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
public:
PieChart(QQuickItem *parent = 0);
QString name() const;
void setName(const QString &name);
QColor color() const;
void setColor(const QColor &color);
void paint(QPainter *painter);
signals:
void colorChanged();
private:
QString m_name;
QColor m_color;
};
//在屬性發(fā)生變化是平绩,發(fā)送信號
void PieChart::setColor(const QColor &color)
{
if (color != m_color) {
m_color = color;
update(); // repaint with the new color
emit colorChanged();
}
}
qml訪問自定義C++類型的函數(shù):
同樣的不能說只是定義成public的函數(shù),就能被qml訪問到漠另,一樣的需要申明和注冊Q_INVOKABLE
:
代碼如下:
Q_INVOKABLE void clearChart();
在qml中就可以如下訪問該接口了:
Item {
width: 300; height: 200
PieChart {
id: aPieChart
anchors.centerIn: parent
width: 100; height: 100
color: "red"
}
MouseArea {
anchors.fill: parent
onClicked: {
//調(diào)用自定義接口
aPieChart.clearChart();
}
}
}
}
備注:public slot也可以被qml直接調(diào)用捏雌!
qml訪問自定義C++類型的信號
信號可以直接訪問:
//c++文件
signals:
void chartCleared();
//qml文件:
PieChart {
id: aPieChart
anchors.centerIn: parent
width: 100; height: 100
color: "red"
//可以直接獲取到chartCleared,不需要特殊的處理
onChartCleared: console.log("The chart has been cleared")
}