在Qt5的QML中使用QZXing识别二维码

前言

ZXing库是一个用来识别二维码的库,QZXing是一个基于Qt的Qt wrapper library,在本文我们使用它和qml开发一个android小应用。

添加QZXing项目

QZXing最常用是作为一个子项目包含在我们的项目中,在我们的项目的pro文件中添加如下的一句:

include(./QZXing/QZXing.pri)

QZXing和我们的pro文件在同一个目录。

qml程序import QtQuick 2.0import QtQuick.Controls 1.3import QtQuick.Window 2.2import QtQuick.Dialogs 1.2import QZXing 2.3ApplicationWindow {title: qsTr(“Hello World”)width: 640height: 480visible: trueproperty real dpi: Screen.pixelDensity.toFixed(2)menuBar: MenuBar {Menu {title: qsTr(“&File”)MenuItem {text: qsTr(“&Open”)onTriggered: messageDialog.show(qsTr(“Open action triggered”));}MenuItem {text: qsTr(“E&xit”)onTriggered: Qt.quit();}}}Image {id: qr_codesource: “qrc:/image/qrcode.png”height: 20 * dpiwidth: 20 * dpifillMode: Image.PreserveAspectFitanchors {top:parent.top; topMargin: 2 * dpi;horizontalCenter: parent.horizontalCenter}}Button {text: qsTr(“O”)height: 10 * dpianchors {top:qr_code.bottom; topMargin: 2 * dpi; left:parent.left; leftMargin: 2 * dpi;right:parent.right; rightMargin: 2 * dpi}onClicked: {decoder.decodeImageQML(qr_code)}}QZXing {id:decoderenabledDecoders: QZXing.DecoderFormat_QR_CODEonDecodingStarted: {console.log(“QZXing decode start!”)}onDecodingFinished: {if (succeeded) {console.log(“success”)} else {console.log(“fail”)}}onTagFound: {messageDialog.show(“QR_CODE:” + tag)}}MessageDialog {id: messageDialogtitle: qsTr(“May I have your attention, please?”){messageDialog.text = caption;messageDialog.open();}}}

然后我们编译我们的程序。这是QZXing会报两个错误。 1.在CameraImageWrapper.cpp文件的147行

#if __cplusplus > 199711Lmemcpy(m, tmpRow->values()..memcpy(m, &tmpRow->values()[0], width);#endif

删除一个点就行了 2.可能我的编译环境中没有iconv.h文件,我在pro文件添加如下解决

DEFINES += NO_ICONV

这样我们的程序就编译通过了。

QML Image to QImage

然后我们测试,没有失败二维码,我调试进decodeImageQML函数,这句

QGraphicsObject *item = qobject_cast<QGraphicsObject*>(imageObj);

失败,item为NULL,没有转化成功。 上网找资料发现,是在Qt5以下版本可以运行。然后看见Qt5开始QML后端实现不同了。然后我看Qt5的文档,发现QML中的Item是QQuickItem类的实例,继承自QObject 和 QQmlParserStatus。在Qt4.8中,QML的Item是QDeclarativeItem的实例,而QDeclarativeItem继承于QGraphicsObject和QDeclarativeParserStatus,所以在qt5以下版本可以运行,,而Qt5就不行了。QQuickItem有一个window函数其然回Item渲染的窗体,其是一个QQuickWindow对象,而QQuickWindow有一个gradWindow函数,其描述如下: Grabs the contents of the window and returns it as an image. 所以我修改了ImageHandler::extractQImage函数

QImage ImageHandler::extractQImage(QObject *imageObj,offsetY,height){#if QT_VERSION >= 0x050000QQuickItem *item = qobject_cast<QQuickItem*>(imageObj);#elseQGraphicsObject *item = qobject_cast<QGraphicsObject*>(imageObj);#endifif (!item) {qDebug() << “Item is NULL”;return QImage();}#if QT_VERSION >= 0x050000QQuickWindow *window = item->window();QImage img = window->grabWindow();#elseQImage img(item->boundingRect().size().toSize(), QImage::Format_RGB32);img.fill(QColor(255, 255, 255).rgb());QPainter painter(&img);QStyleOptionGraphicsItem styleOption;item->paint(&painter, &styleOption);#endifif(offsetX == 0 && offsetY == 0 && width == 0 && height == 0)return img;else{return img.copy(offsetX, offsetY, width, height);}}

OK,识别成功,有图为证

忘了 在QML中使用QZXing,需要在main函数中注册一下

main(int argc, char *argv[]){QApplication app(argc, argv);QZXing::registerQMLTypes();QQmlApplicationEngine engine;engine.load(QUrl(QStringLiteral(“qrc:/main.qml”)));return app.exec();}

为什么?答:点线杆上贴着”“此处不许小便!”

在Qt5的QML中使用QZXing识别二维码

相关文章:

你感兴趣的文章:

标签云: