最近做项目中遇到需要采集产品的条形码和二维码进行保存显示,并上传服务器或企业ERP系统,于是针对无线扫码枪和二维码扫码枪做了数据采集测试。
扫码枪本身是一个输入设备,类似键盘输入。条码都是ASCII字符,最后一个字符为回车键,一般扫码枪连接电脑后,光标焦点放在编辑框,扫码后数据就会自动输入到编辑框,本文主要讲解如何在没有编辑框的时候,通过拦截WM_CHAR消息获取输入条码的具体数据。
1、软硬件配置
- 科密无线扫码枪(条形码),型号:YX-38
- 软件环境 Qt5.9.6
2、解决思路
1.一般扫码枪是通过串口进行采集,其优点是可实现无焦点采集,可循环存到一个固定的内存地址,缺点是串口必须接一根串口线,用户体验不太好;
2.Qt采用键盘事件来判别条形码输入的具体内容,因此可以通过监听虚拟键盘的输入来判定扫码枪的输入,从而实现无焦点采集。
上图是扫码枪设置的图,可以设置不同的工作模式,在扫码枪超出无线传输的距离范围后,可以使用 盘点模式,这样扫码数据就保存到扫码枪,盘点完成后再扫 数据上传,这样就可以实现离线的货物盘点了,这一点还是比较人性化的,不过这些工作模式我这里没有一一测试。
3、具体代码实现
3.1 Qt自带的键盘事件QEvent::KeyPress
private slots:
//申明KeyPress函数
void keyPressEvent(QKeyEvent* event);
以上是头文件的函数申明,其具体实现代码如下:
void Widget::keyPressEvent(QKeyEvent* event)
{
switch(event->key())
{
case Qt::Key_Down:
{
qDebug()<<"ok";
}
break;
case Qt::Key_F1:
{
qDebug()<<"ssss";
}
}
if (0x30 <= event->key() && 0x39 >= event->key())
{
char st=event->key();
QString str_ascii = QString(st);
qDebug()<key();
}
else if (0x41 <= event->key() && 0x48 >= event->key())
{
qDebug()<key();
}else
{
qDebug()<key();
}
}
键盘事件中的按键对应值如下表所示:
3.2 自己写全局的键盘监测函数
使用notify()函数来实现键盘的监控
bool GlobalApplication::notify(QObject *obj, QEvent *e)
{
const QMetaObject* objMeta = obj->metaObject();
QString clName = objMeta->className();
// qDebug()<type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast(e);
if(keyEvent->key() == 16777220)
{
qDebug()<key();
QString str_ascii = QString(st);
strinput +=str_ascii;
// qDebug()<type() == QEvent::KeyPress)
// {
// QKeyEvent *keyEvent = static_cast(e);
// if(keyEvent->key() == Qt::Key_F1)
// {
// qDebug() << clName;
// qDebug() << "F1";
// }
// // widget->keyPress(keyEvent);
// }
// else if(e->type() == QEvent::MouseButtonPress)
// {
// QMouseEvent *mouseEvent = static_cast(e);
// if(mouseEvent->buttons() == Qt::LeftButton)
// qDebug() << "left";
// }
//}
return QApplication::notify(obj,e);
}
这个函数也可用作鼠标的监控,其中注释的部分涉及到鼠标的监控。全局监控需要在main.cpp文件里,设定为全局类GlobalApplication
int main(int argc, char *argv[])
{
GlobalApplication a(argc, argv);
// QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
3.3 附上全部代码及测试效果
globalapplication.h
#ifndef GLOBALAPPLICATION_H
#define GLOBALAPPLICATION_H
#include
class GlobalApplication : public QApplication
{
public:
GlobalApplication(int&argc,char **argv);
~GlobalApplication();
bool notify(QObject*,QEvent *);
void setWindowInstance(QWidget *wnd);
private:
QWidget *widget;
QString strinput;
};
#endif // GLOBALAPPLICATION_H
globalapplication.cpp
#include "globalapplication.h"
#include
#include
#include
GlobalApplication::GlobalApplication(int &argc,char **argv):
QApplication(argc,argv)
{
}
GlobalApplication::~GlobalApplication()
{
}
void GlobalApplication::setWindowInstance(QWidget *wnd)
{
widget = wnd;
}
bool GlobalApplication::notify(QObject *obj, QEvent *e)
{
const QMetaObject* objMeta = obj->metaObject();
QString clName = objMeta->className();
// qDebug()<type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast(e);
if(keyEvent->key() == 16777220)
{
qDebug()<key();
QString str_ascii = QString(st);
strinput +=str_ascii;
// qDebug()<type() == QEvent::KeyPress)
// {
// QKeyEvent *keyEvent = static_cast(e);
// if(keyEvent->key() == Qt::Key_F1)
// {
// qDebug() << clName;
// qDebug() << "F1";
// }
// // widget->keyPress(keyEvent);
// }
// else if(e->type() == QEvent::MouseButtonPress)
// {
// QMouseEvent *mouseEvent = static_cast(e);
// if(mouseEvent->buttons() == Qt::LeftButton)
// qDebug() << "left";
// }
//}
return QApplication::notify(obj,e);
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include
#include "dialog.h"
#include "form.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
Dialog *p_dialog;
Form *p_form;
private slots:
void on_pushButton_Load_clicked();
void on_pushButton_test_clicked();
void keyPressEvent(QKeyEvent* event);
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "dialog.h"
#include
#include
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
p_dialog = NULL;
p_form = NULL;
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_Load_clicked()
{
if(p_dialog == NULL)
{
p_dialog =new Dialog();
p_dialog->setWindowTitle(QString::fromLocal8Bit("虚拟键盘测试"));
p_dialog->show();
qDebug()<<"Test"<show();
}
}
void Widget::on_pushButton_test_clicked()
{
if(p_form == NULL)
{
p_form =new Form();
p_form->setWindowTitle(QString::fromLocal8Bit("测试"));
p_form->show();
// qDebug()<<"Test"<show();
}
}
void Widget::keyPressEvent(QKeyEvent* event)
{
switch(event->key())
{
case Qt::Key_Down:
{
qDebug()<<"ok";
}
break;
case Qt::Key_F1:
{
qDebug()<<"ssss";
}
}
// if (0x30 <= event->key() && 0x39 >= event->key())
// {
// char st=event->key();
// QString str_ascii = QString(st);
// qDebug()<key();
// }
// else if (0x41 <= event->key() && 0x48 >= event->key())
// {
// qDebug()<key();
// }
// else
// {
// qDebug()<key();
// }
}
3.4 代码仓库
码云仓库地址
下一节内容 如何区分键盘输入还是扫码枪输入。