文章目录
问题
公司设备由不同模块组成,为了管理这些模块,公司为每个模块分配了SN,每个SN都有一个二维码,操作员通过扫码二维码把SN输入到物料管理系统中。
物料管理系统是我开发的。二维码输入时,遇到字符重复问题:对于“CW-HT6020Z1100001376”,系统文本框得到的字符串是正确的,我的程序得到的是"CCWW–HHTT66002200ZZ11110000000011337766", 每个字符重复2次,或者4次,甚至11次。
分析
扫描枪基本模型
关于扫描枪,对于PC来说,是个输入设备,对应于PC的键盘,以回车键表示输入完成。
基本处理代码如下:
void MainWindow::keyPressEvent(QKeyEvent* event)
{
static QString strMsg;
if(event->key() == Qt::Key_Return){//enter
qDebug() << strMsg;
strMsg.clear();
}else{
strMsg += event->text();
}
}
我试验了该段代码,在空的mainwindow下面,仅输出了""。所以,我才用了eventFilter来过滤事件。
EventFiler基本模型
请参考void QObject::installEventFilter(QObject *filterObj).
我的代码如下:
//keypressfiler.h //header
class CKeyPressFilter : public QObject
{
Q_OBJECT
public:
explicit CKeyPressFilter(QObject *parent=Q_NULLPTR);
protected:
bool eventFilter(QObject *obj, QEvent *event);
};
//keypressfiler.cpp //cpp
CKeyPressFilter::CKeyPressFilter(QObject *parent)
:QObject (parent)
{
}
bool CKeyPressFilter::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
static QString strModSn;
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (Qt::Key_Return == keyEvent->key())
{
qDebug()<<strModSn;
if (!strModSn.isEmpty())
{
strModSn.remove(QChar(' '));
emit signal_newModuleSn(strModSn);
}
strModSn.clear();
}
else
{
char ch = keyEvent->key();
if (ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z'
|| ch == '-' || ch == '(' || ch == ')' || ch ==' ')
{
strModSn += QString(ch);
}
else
strModSn.clear();
}
}
return QObject::eventFilter(obj, event);
}
//mainwindow.cpp //for use
CKeyPressFilter *pKeyPressFlt = new CKeyPressFilter(this);
QCoreApplication::instance()->installEventFilter(pKeyPressFlt);
这份代码可以捕获扫码强输入,但是出现了重复字符问题。
记录QKeyEvent
QKeyEvent继承于QInputEvent,而QInputEvent继承于QEvent.QEvent中type()函数返回事件类型,查阅了type的说明后发现QKeyEvent只有两个事件KeyPress和KeyRelease。所以,只要打印了每次QKeyEvent的type()和text(),就知道内幕了。
bool CKeyPressFilter::eventFilter(QObject *obj, QEvent *event)
{
QEvent::Type tpCurr = event->type();
if (tpCurr == QEvent::KeyPress || tpCurr == QEvent::KeyRelease) {
static QString strModSn;
static QString strTest;
static QEvent::Type tpPre = QEvent::None;
static char ch;
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (!keyEvent->text().isEmpty() && tpPre != tpCurr)
{
if (QEvent::None != tpPre)
{
if (QEvent::KeyRelease == tpCurr)
{
ch = static_cast<char>(keyEvent->key());
strTest += keyEvent->text();
}
}
tpPre = tpCurr;
}
strModSn += keyEvent->text();
qDebug()<<tpCurr<<" "<<keyEvent->text();
if (Qt::Key_Return == keyEvent->key())
{
qDebug()<<strModSn;
qDebug()<<strTest;
strModSn.clear();
strTest.clear();
tpPre = QEvent::None;
}
}
}
打印结果如下:
QEvent::Type(KeyPress) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) "C"
QEvent::Type(KeyPress) "C"
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) "C"
QEvent::Type(KeyRelease) "C"
QEvent::Type(KeyRelease) "C"
QEvent::Type(KeyRelease) "C"
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) "W"
QEvent::Type(KeyPress) "W"
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) "W"
QEvent::Type(KeyRelease) "W"
QEvent::Type(KeyRelease) "W"
QEvent::Type(KeyRelease) "W"
QEvent::Type(KeyPress) "-"
QEvent::Type(KeyPress) "-"
QEvent::Type(KeyRelease) "-"
QEvent::Type(KeyRelease) "-"
QEvent::Type(KeyRelease) "-"
QEvent::Type(KeyRelease) "-"
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) "H"
QEvent::Type(KeyPress) "H"
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) "H"
QEvent::Type(KeyRelease) "H"
QEvent::Type(KeyRelease) "H"
QEvent::Type(KeyRelease) "H"
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) "T"
QEvent::Type(KeyPress) "T"
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) "T"
QEvent::Type(KeyRelease) "T"
QEvent::Type(KeyRelease) "T"
QEvent::Type(KeyRelease) "T"
QEvent::Type(KeyPress) "6"
QEvent::Type(KeyPress) "6"
QEvent::Type(KeyRelease) "6"
QEvent::Type(KeyRelease) "6"
QEvent::Type(KeyRelease) "6"
QEvent::Type(KeyRelease) "6"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyPress) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyPress) "2"
QEvent::Type(KeyPress) "2"
QEvent::Type(KeyRelease) "2"
QEvent::Type(KeyRelease) "2"
QEvent::Type(KeyRelease) "2"
QEvent::Type(KeyRelease) "2"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) ""
QEvent::Type(KeyPress) "Z"
QEvent::Type(KeyPress) "Z"
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) "Z"
QEvent::Type(KeyRelease) "Z"
QEvent::Type(KeyRelease) "Z"
QEvent::Type(KeyRelease) "Z"
QEvent::Type(KeyPress) " "
QEvent::Type(KeyPress) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyRelease) " "
QEvent::Type(KeyPress) "1"
QEvent::Type(KeyPress) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyPress) "1"
QEvent::Type(KeyPress) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyPress) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyRelease) "0"
QEvent::Type(KeyPress) "1"
QEvent::Type(KeyPress) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyRelease) "1"
QEvent::Type(KeyPress) "3"
QEvent::Type(KeyPress) "3"
QEvent::Type(KeyRelease) "3"
QEvent::Type(KeyRelease) "3"
QEvent::Type(KeyRelease) "3"
QEvent::Type(KeyRelease) "3"
QEvent::Type(KeyPress) "7"
QEvent::Type(KeyPress) "7"
QEvent::Type(KeyRelease) "7"
QEvent::Type(KeyRelease) "7"
QEvent::Type(KeyRelease) "7"
QEvent::Type(KeyRelease) "7"
QEvent::Type(KeyPress) "7"
QEvent::Type(KeyPress) "7"
QEvent::Type(KeyRelease) "7"
QEvent::Type(KeyRelease) "7"
QEvent::Type(KeyRelease) "7"
QEvent::Type(KeyRelease) "7"
QEvent::Type(KeyPress) "\r"
" CCCCCCWWWWWW------HHHHHHTTTTTT666666000000 222222000000ZZZZZZ 111111111111000000000000000000000000111111333333777777777777\r"
" -60 20 1100001377"
总结一下,事件模型有两种
# 模型1
QEvent::Type(KeyPress) "3"
QEvent::Type(KeyPress) "3"
QEvent::Type(KeyRelease) "3"
QEvent::Type(KeyRelease) "3"
QEvent::Type(KeyRelease) "3"
QEvent::Type(KeyRelease) "3"
# 模型2
QEvent::Type(KeyPress) "H"
QEvent::Type(KeyPress) "H"
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) ""
QEvent::Type(KeyRelease) "H"
QEvent::Type(KeyRelease) "H"
QEvent::Type(KeyRelease) "H"
QEvent::Type(KeyRelease) "H"
去除空字符串“”后,模型2就编程模型1了。可以发现,只需在KeyPress变为KeyRelease时将该字符串追加到strModSn后即可。
优化
最终代码如下
//keypressfiler.h //header
class CKeyPressFilter : public QObject
{
Q_OBJECT
public:
explicit CKeyPressFilter(QObject *parent=Q_NULLPTR);
protected:
bool eventFilter(QObject *obj, QEvent *event);
};
//keypressfiler.cpp //cpp
CKeyPressFilter::CKeyPressFilter(QObject *parent)
:QObject (parent)
{
}
bool CKeyPressFilter::eventFilter(QObject *obj, QEvent *event)
{
QEvent::Type tpCurr = event->type();
if (tpCurr == QEvent::KeyPress || tpCurr == QEvent::KeyRelease) {
static QString strModSn;
static QEvent::Type tpPre = QEvent::None;
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (Qt::Key_Return == keyEvent->key())
{
qDebug()<<strModSn;
strModSn.clear();
tpPre = QEvent::None;
}
if (!keyEvent->text().isEmpty() && tpPre != tpCurr)
{
if (QEvent::None != tpPre)
{
if (QEvent::KeyRelease == tpCurr)
{
strModSn += keyEvent->text();
}
}
tpPre = tpCurr;
}
}
return QObject::eventFilter(obj, event);
}
//mainwindow.cpp //for use
CKeyPressFilter *pKeyPressFlt = new CKeyPressFilter(this);
QCoreApplication::instance()->installEventFilter(pKeyPressFlt);
测试,符合预期。大功告成。