人脸识别系统(3)--C++与QML混合编程

使用Qt Quick技术可以快速的构建流畅的界面,而且具有动画等各种绚丽的效果。但它也有很多局限性,比如在网络访问、硬件操作、文件处理等方面,所以在很多时候我们需要混合使用C++和QML,比如使用QML构建界面,使用C++来实现非界面的业务逻辑等。这样也就涉及到了QML和C++之间的交互了。其实,QML的很多基本类型本来也是通过C++来实现的,比如Item对应QQuickItem类,Image对应QQuickImage类等。

前面人脸识别系统开发(2) – QML基础语法中提到的:

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

一、在QML中使用C++类和对象

Qt提供了2种在QML中访问C++对象的方式:
1. 在C++中实现一个类,注册该类为QML环境的一个类型,然后在QML中使用该类型创建一个对象(即声明一个控件)。
2. 在C++中构造一个对象,将这个对象设置为QML的上下文属性,是QML环境中直接使用该属性。

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();

    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);

    void beginGrapFaceImage();
    void endGrapFaceImage();

    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

二、在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
  1. 使用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

猜你喜欢

转载自blog.csdn.net/jack_20/article/details/79034759
今日推荐