文档章节

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

首席吹牛官
 首席吹牛官
发布于 2015/05/22 12:59
字数 703
阅读 369
收藏 1

前言

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

添加QZXing项目

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

include(./QZXing/QZXing.pri)

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

qml程序

import QtQuick 2.0
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QZXing 2.3

ApplicationWindow {
    title: qsTr("Hello World")
    width: 640
    height: 480
    visible: true

    property 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_code
        source: "qrc:/image/qrcode.png"
        height: 20 * dpi
        width: 20 * dpi
        fillMode: Image.PreserveAspectFit
        anchors {top:parent.top; topMargin: 2 * dpi;horizontalCenter: parent.horizontalCenter}

    }

    Button {
        text: qsTr("O")
        height: 10 * dpi
        anchors {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:decoder
        enabledDecoders: QZXing.DecoderFormat_QR_CODE
        onDecodingStarted: {
            console.log("QZXing decode start!")
        }

        onDecodingFinished: {
            if (succeeded) {
                console.log("success")
            } else {
                console.log("fail")
            }
        }

        onTagFound: {
            messageDialog.show("QR_CODE:" + tag)
        }




    }



    MessageDialog {
        id: messageDialog
        title: qsTr("May I have your attention, please?")

        function show(caption) {
            messageDialog.text = caption;
            messageDialog.open();
        }
    }

}

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

#if __cplusplus > 199711L
        memcpy(m, tmpRow->values()..data(), width);
#else
        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,
                                   const double offsetX, const double offsetY,
                                   const double width, const double height)
{
#if QT_VERSION >= 0x050000
    QQuickItem *item = qobject_cast<QQuickItem*>(imageObj);
#else
    QGraphicsObject *item = qobject_cast<QGraphicsObject*>(imageObj);
#endif
    if (!item) {
        qDebug() << "Item is NULL";
        return QImage();
    }
#if QT_VERSION >= 0x050000
    QQuickWindow *window = item->window();
    QImage img = window->grabWindow();
#else
    QImage img(item->boundingRect().size().toSize(), QImage::Format_RGB32);
    img.fill(QColor(255, 255, 255).rgb());
    QPainter painter(&img);
    QStyleOptionGraphicsItem styleOption;
    item->paint(&painter, &styleOption);
#endif

    if(offsetX == 0 && offsetY == 0 && width == 0 && height == 0)
        return img;
    else
    {
        return img.copy(offsetX, offsetY, width, height);
    }
}

OK,识别成功,有图为证
这里写图片描述

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

#include <QApplication>
#include <QQmlApplicationEngine>
#include "QZXing.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QZXing::registerQMLTypes();

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

© 著作权归作者所有

首席吹牛官
粉丝 9
博文 368
码字总数 191938
作品 0
闵行
程序员
私信 提问
加载中

评论(1)

s
shui0
你好,请问一下这个方法是否在安卓6.0以上的机子测试过?
Qt5 路线?

从 Qt 官方刚发布的blog Thoughts about Qt 5我们可以了解到下一版 Qt 的动向。 愿景 Qt 5.0 will be the foundation for a new way of developing applications. While offering all of th......

晨曦之光
2012/05/08
828
0
qml+opencv(一)

前言 突然想起opencv,一直想做人脸识别,可是理论基础太水,只能慢慢来,去年学习了一会,然后公司让我去搞app和网络,就一直搁着,现在学习qml,突然想能不能在qml里面使用opencv,所以就有...

首席吹牛官
2015/05/22
1K
0
Qt实用技巧:在Qt Gui程序中嵌入qml界面(可动态覆盖整个窗口)

原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78486552 前话 使用qml做界面比使用qtgui强大很多,当然内存使用增大,...

qq21497936
2017/11/09
0
0
Qt5.7以及5.8在cmake工程中使用C++14编译遇到的问题及解决方案

最近在编译一个用到C++14特性的工程时,遇到这样一个问题。 编译时报:error: ‘decay_t’ is not a member of ‘std’ std::decayt属于C++14加入的特性,需要 #include <typetraits>,set(S...

lieefu
2016/12/27
638
0
Qt5 结构及模块组成?

作为一个Qt的粉丝,对将于明年发布的Qt5充满了期待。可是想想Qt5将发生的巨大变化,心底又有点不安。Qt5到底会变成什么样呢? 看看近期Qt5的一些大动作: 从 QtCore中移除 QSettings以及对Q...

晨曦之光
2012/05/08
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
今天
5
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
今天
6
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
今天
4
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
今天
7
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部