扫描枪重复字符问题

文章目录

问题

公司设备由不同模块组成,为了管理这些模块,公司为每个模块分配了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);

测试,符合预期。大功告成。

上一篇:利用机器人类Robot写出自动登录QQ的小代码


下一篇:FFmpeg-之X264视频编码与FAAC音频编码(四),kotlin反编译文件夹