版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接和本聲明。
本文連接:https://blog.csdn.net/china_jeffery/article/details/78954822
使用Qt Quick技術能夠快速的構建流暢的界面,並且具備動畫等各類絢麗的效果。但它也有不少侷限性,好比在網絡訪問、硬件操做、文件處理等方面,因此在不少時候咱們須要混合使用C++和QML,好比使用QML構建界面,使用C++來實現非界面的業務邏輯等。這樣也就涉及到了QML和C++之間的交互了。其實,QML的不少基本類型原本也是經過C++來實現的,好比Item對應QQuickItem類,Image對應QQuickImage類等。html
前面人臉識別系統開發(2) – QML基礎語法中提到的:git
import HFR.IDCard 1.0 // C++中IDCardReader類註冊爲QML對象
import HFR.VideoItem 1.0 // C++中VideoItem類註冊爲QML對象
1
2
就是典型的QML訪問C++的例子,經過將C++類註冊爲QML對象,來讓QML訪問。編程
C++調用QML的例子如:網絡
QMetaObject::invokeMethod(g_Root, "showMsg",
Q_ARG(QVariant, QObject::tr("人臉檢測模塊加載失敗")));
1
2
1、在QML中使用C++類和對象
Qt提供了2種在QML中訪問C++對象的方式:
1. 在C++中實現一個類,註冊該類爲QML環境的一個類型,而後在QML中使用該類型建立一個對象(即聲明一個控件)。
2. 在C++中構造一個對象,將這個對象設置爲QML的上下文屬性,是QML環境中直接使用該屬性。ide
1.1 定義一個能夠導出的C++類
以OpenCVCamera類爲例,該類位於HFR\OpenCVCamera.h文件:函數
// OpenCVCamera摘要
//
class OpenCVCamera : public QObject { // 直接或間接從QObject繼承
Q_OBJECT // 使用Q_OBJECT宏動畫
// 使用Q_PROPERTY宏來定義能夠被QML環境訪問的屬性
// 詳細語法見:http://doc.qt.io/qt-5/qobject.html#Q_PROPERTY
//
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
public:
explicit OpenCVCamera(QObject *parent = 0);
virtual ~OpenCVCamera();ui
bool enabled() const;
virtual void setEnabled(bool b);
bool readMat(cv::Mat &frame);
public slots:
// 使用Q_INVOKABLE宏來修飾類的成員函數,讓QML中能夠調用該方法
//
Q_INVOKABLE void grapImage(bool bFace, int iNum);
Q_INVOKABLE void recognize(QString name,
QString sex,
QString nation,
QString birthday,
QString photoPath,
QString address,
QString cardNumber);
private slots:
void grapFaceFrameTimeProc();
void recognizeResultNotify(bool bPass);
signals:
void enabledChanged(bool bEnable);.net
void beginGrapFaceImage();
void endGrapFaceImage();htm
void newGrapImage(const GrapImageData& data);
void beginRecognize();
void endRecognize(bool result, double confidence);
void noVideoInputSignal();
void recognizeFinish(const HFResult &result);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
還可使用Q_ENUMS將枚舉類型註冊到QML中。
1.2 將C++類註冊爲QML可用類型
qmlRegisterType<OpenCVCamera>("HFR.OpenCV", 1, 0, "OpenCVCamera");
1
1.3 在QML中使用導入的類型
import HFR.IDCard 1.0
IDCardReader {
id: idCardReader;
}
1
2
3
4
5
1.4 將C++對象設置爲QML上下文
在C++中構造一個對象,將這個對象設置爲QML的上下文屬性,是QML環境中直接使用該屬性。
如將pCamera,pCameraPreview對象設置爲QML環境上下文,在QML中就能夠直接訪問和使用:
OpenCVCamera *pCamera = new OpenCVCamera();
QObject::connect(pCamera, SIGNAL(newGrapImage(const GrapImageData&)), pGrapImageModel, SLOT(addGrapImage(const GrapImageData&)));
OpenCVCameraPreview* pCameraPreview = new OpenCVCameraPreview();
engine.rootContext()->setContextProperty("camera", pCamera);
engine.rootContext()->setContextProperty("cameraPreview", pCameraPreview);
1
2
3
4
5
6
7
QML中使用:
camera.recognize(idCardReader.name,
idCardReader.sex,
idCardReader.nation,
idCardReader.birthday,
idCardReader.photoPath,
idCardReader.address,
idCardReader.cardNumber
);
1
2
3
4
5
6
7
8
cameraPreview.enabled = false;
1
2、在C++中使用QML對象
在C++中使用QML對象的步驟以下:
1. 使用objectName查找到QML對象。
QObject *root = NULL;
QList<QObject*> rootObjects = engine.rootObjects();
for (int i = 0; i < rootObjects.size(); i++) {
if (rootObjects.at(i)->objectName() == "root") {
root = rootObjects.at(i);
break;
}
}
1
2
3
4
5
6
7
8
使用QMetaObject::invokeMethod來調用QML函數。
if (g_Root) {
QMetaObject::invokeMethod(g_Root, "showMsg",
Q_ARG(QVariant, QObject::tr("人臉檢測模塊加載失敗")));
}
1
2
3
4
關於「C++與QML的混合編程」能夠參考:
1. Qt官方文檔:Integrating QML and C++
2. http://blog.csdn.net/foruok/article/details/32698603
人臉識別系統項目地址:https://gitee.com/china_jeffery/HFR_OpenSource
———————————————— 版權聲明:本文爲CSDN博主「china_jeffery」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。 原文連接:https://blog.csdn.net/china_jeffery/article/details/78954822