Qt5.8 QML和C++混合程式設計的兩種方式(附帶原始碼)
Qt5.8 QML和C++混合程式設計的兩種方式(附帶原始碼)
編譯環境:win10 專業版 Qt5.8
Qt 提供了兩種在 QML 環境中使用 C++ 物件的方式:
上手敲一下,很快就能理解點選開始,中間的圖形開始變化,上面顯示時間,點選停止,不再變化,點選RGB,應用這個演算法,按鈕顯示為下一個演算法,退出按鈕退出程式
************************************************************************************************************************************************************************************************************************************************
1.C++ 中實現一個類,註冊到 QML 環境中, QML 環境中使
用該型別建立物件
QML中使用C++物件
(1)實現可以匯出的C++類colormaker.h
#ifndef COLORMAKER_H #define COLORMAKER_H #include <QObject> #include <QColor> #include <QTimerEvent> class ColorMaker : public QObject { Q_OBJECT // 如果你要匯出的類定義了想在 QML 中使用列舉型別,可以使用 Q_ENUMS 巨集將該列舉註冊到元物件系統中。 Q_ENUMS(generate) //Q_PROPERTY 巨集用來定義可通過元物件系統訪問的屬性,通過它定義的屬性,可以在 QML 中訪問、修改,也可以在屬性變化時發射特定的訊號。 //READ 宣告一個讀取屬性的函式,該函式一般沒有引數,返回定義的屬性。 //WRITE [可選]宣告一個設定屬性的函式。它指定的函式,只能有一個與屬性型別匹配的引數,必須返回 void 。 //NOTIFY [可選]給屬性關聯一個訊號(該訊號必須是已經在類中宣告過的),當屬性的值發生變化時就會觸發該訊號。訊號的引數,一般就是你定義的屬性。 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) Q_PROPERTY(QColor timeColor READ timeColor ) public: explicit ColorMaker(QObject *parent = 0); //列舉該變數 (5中顏色的演算法) enum generate{ randomRGB, randomRed, randomGreen, randomBlue, increase //(顏色變化演算法為)直線增長模式 }; QColor color() const; void setColor(const QColor &color); QColor timeColor() const; //在定義一個類的成員函式時使用 Q_INVOKABLE 巨集來修飾,就可以讓該方法被元物件系統呼叫。這個巨集必須放在返回型別前面。 Q_INVOKABLE generate algorithm() const; //返回型別為列舉型別GenerateAlgorithm; 這是一個演算法函式 Q_INVOKABLE void setAlgouthm(generate algorithm); //設定為具體使用哪一個顏色的演算法 signals: //定義colorChanged() / currentTime() 兩個訊號 void colorChanged(const QColor &color); //顏色改變的訊號 void currentTimer(const QString &strTime); //當前時間的訊號 public slots: //定義了 start() / stop() 兩個槽 void start(); void stop(); protected: void timerEvent(QTimerEvent *event); //時間事件 private: generate myGenerate; //具體使用的哪一種演算法 QColor myColor; //現在的顏色 int colorTimer; //定時器的ID }; #endif // COLORMAKER_H
colormaker.cpp
#include "colormaker.h" #include <QDateTime> #include <QColor> ColorMaker::ColorMaker(QObject *parent) : QObject(parent) , myGenerate(randomRGB) //初始化一個隨機的顏色演算法 , myColor(Qt::black) //初始化賦值為黑色 , colorTimer(0) { qsrand(QDateTime::currentDateTime().toTime_t()); } //單純的呼叫該函式, 確定設定顏色順便會發射顏色改變的訊號 QColor ColorMaker::color() const { return myColor; } //顏色由當前時間作為引數來生成 void ColorMaker::setColor(const QColor &color) { myColor = color; emit colorChanged(myColor); } //顏色由當前時間作為引數來生成 QColor ColorMaker::timeColor() const { QTime time = QTime::currentTime(); //獲取當前現在的時間 int r = time.hour(); int g = time.minute(); int b = time.second(); return QColor::fromRgb(r, g, b); } //傳送出去一個(演算法)的值 [確定是使用哪一種演算法,RGB? Green? Red? Blue? ] ColorMaker::generate ColorMaker::algorithm() const { return myGenerate; } //賦值給類成員 void ColorMaker::setAlgouthm(ColorMaker::generate algorithm) { myGenerate = algorithm; } //啟動時間 void ColorMaker::start() { if(colorTimer == 0) { colorTimer = startTimer(1000); } } //停止計時器的使用 void ColorMaker::stop() { if(colorTimer > 0) { killTimer(colorTimer); //終止計時器,銷燬 colorTimer = 0; } } //timerEvent事件訊息 void ColorMaker::timerEvent(QTimerEvent *event) { if(event->timerId() == colorTimer) { switch (myGenerate) { case randomRGB: myColor.setRgb(qrand()%255, qrand()%255, qrand()%255); break; case randomRed: myColor.setRed(qrand()%255); break; case randomGreen: myColor.setGreen(qrand()%255); break; case randomBlue: myColor.setBlue(qrand()%255); break; default: { int r = myColor.red() + 10; int g = myColor.green() + 10; int b = myColor.blue() + 10; myColor.setRgb(r%255, g%255, b%255); } break; } //發射這兩個訊號 emit colorChanged(myColor); emit currentTimer(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); } else { timerEvent(event); } }
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <colormaker.h>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
// 註冊一個 QML 型別 ;註冊一個單例型別,然後就可以在qml裡面呼叫了
//qmlRegisterType() 的第一個引數 uri ,讓你指定一個唯一的包名,類似 Java 中的那種,
//一是用來避免名字衝突,而是可以把多個相關類聚合到一個包中方便引用。
//比如我們常寫這個語句 "import QtQuick.Controls 1.1" ,其中的 "QtQuick.Controls" 就是包名 uri ,而 1.1 則是版本,是 versionMajor 和 versionMinor 的組合。
//qmlName 則是 QML 中可以使用的類名。
qmlRegisterType<ColorMaker>("qt.an.colormaker", 1, 0, "ColorMaker"); //只增加了這一句
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0 //控制版本
import QtQuick.Layouts 1.0 //佈局版本
import qt.an.colormaker 1.0 //匯入自定義的C++的類, 這是其自定義的包名和主、次版本號
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("2018_2_26_qml與C++混合程式設計")
Text {
id: timeLabel;
anchors.top: parent.top;
anchors.horizontalCenter: parent.horizontalCenter;
font.pixelSize: 40;
}
//在這裡呼叫了C++類, 建立了一個介意供qml使用的C++物件
ColorMaker {
id: colorMaker;
}
//中間顯示顏色變化的矩形
Rectangle {
id:colorRect;
anchors.centerIn: parent;
width: 300;
height: 300;
color: "Green";
}
//開始按鈕
Button {
id: start;
text: "start";
anchors.left: parent.left;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
colorMaker.start();
}
}
//結束按鈕
Button {
id: stop;
text: "stop";
anchors.left: start.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
colorMaker.stop();
}
}
//Javascript函式
function changetAlgorithm(button, algorithm) {
switch(algorithm)
{
case 0:
button.text = "RGB";
break;
case 1:
button.text = "Red";
break;
case 2:
button.text = "Green";
break;
case 3:
button.text = "Blue";
break;
default:
button.text = "increase";
break;
}
}
//顏色演算法按鈕
Button {
id: colorAlgorithm;
text: "RGB";
anchors.left: stop.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
var algorithm = (colorMaker.algorithm() +1) % 5;
changetAlgorithm(colorAlgorithm, algorithm); //changetAlgorithm是後面的Javascript函式
colorMaker.setAlgouthm(algorithm);
}
}
//退出按鈕
Button {
id: quit;
text: "quit";
anchors.left: colorAlgorithm.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
Qt.quit();
}
}
//關聯控制元件colorMaker 和 槽函式onCurrentTimer
Connections {
target: colorMaker; //接收事件的物件
onCurrentTimer: { //收到事件時的處理函式
timeLabel.text = strTime; //strTime從currentTimer裡傳送過來的
timeLabel.color = colorMaker.timeColor;
}
}
Connections {
target: colorMaker;
onColorChanged: {
colorRect.color = colorMaker.color;
}
}
}
專案名稱:2018_2_26_qmlANDc
******************************************************************************************************************
2.在 C++ 中構造一個物件,將這個物件設定為 QML 的上下文
屬性,在 QML 環境中直接使用改屬性
colormaker.h 不變,和上面一樣
colormaker.cpp 不變,和上面一樣
main.cpp 有變化
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <colormaker.h>
#include <QQmlContext>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("colorMaker", new ColorMaker); //新增加的一句,用於註冊可以被qml使用的C++物件
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
main.qml 有變化, 但是是只有兩處需要註釋掉
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
//import qt.an.colormaker 1.0 //不需要匯入這個包
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("2018_2_26_qml與C++混合程式設計")
Text {
id: timeLabel;
anchors.top: parent.top;
anchors.horizontalCenter: parent.horizontalCenter;
font.pixelSize: 40;
}
//不需要在這裡建立這個物件了
// ColorMaker {
// id: colorMaker;
// }
Rectangle {
id:colorRect;
anchors.centerIn: parent;
width: 300;
height: 300;
color: "Green";
}
Button {
id: start;
text: "start";
anchors.left: parent.left;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
colorMaker.start();
}
}
Button {
id: stop;
text: "stop";
anchors.left: start.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
colorMaker.stop();
}
}
//Javascript函式
function changetAlgorithm(button, algorithm) {
switch(algorithm)
{
case 0:
button.text = "RGB";
break;
case 1:
button.text = "Red";
break;
case 2:
button.text = "Green";
break;
case 3:
button.text = "Blue";
break;
default:
button.text = "increase";
break;
}
}
Button {
id: colorAlgorithm;
text: "RGB";
anchors.left: stop.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
var algorithm = (colorMaker.algorithm() +1) % 5;
//changetAlgorithm是上面的Javascript函式, 必須先定義,後使用
changetAlgorithm(colorAlgorithm, algorithm);
colorMaker.setAlgouthm(algorithm);
}
}
Button {
id: quit;
text: "quit";
anchors.left: colorAlgorithm.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
Qt.quit();
}
}
Connections {
target: colorMaker;
onCurrentTimer: {
timeLabel.text = strTime;
timeLabel.color = colorMaker.timeColor;
}
}
Connections {
target: colorMaker;
onColorChanged: {
colorRect.color = colorMaker.color;
}
}
}
******************************************************************************************************************
建立的步驟如下: