QT 利用数组简单实现双键,多键输入判定

文章介绍了在Qt中处理键盘事件时,如何在按下多个键时记录键值并避免键值被覆盖的问题。通过使用一个长度为2的数组存储键值,在keyPressEvent和keyReleaseEvent中管理数组内容,并借助定时器实现即时响应。当遇到同时按下超过数组长度的键时,会出现延迟反馈,作者提议扩展数组长度以解决该问题。
摘要由CSDN通过智能技术生成

        从一位大佬的文章中了解到键盘事件在按下第二个键位时,keyPressEvent触发,第一个键位数据会被第二个键位数据顶替(ev->key()),这样就使得我们无法直接按下多键运行。但是当我们松开第一个键位时,此时会触发一次keyReleaseEvent,这时的键值又被更替为第一个键位值。

        根据以上情况,我们在keyPressEvent,keyReleaseEvent中做点操作,定义一个长度为2的数组,当keyPressEvent触发时存储键值,再用一个函数来根据数组中的值触发目的操作。用一个定时器来不断调用这个函数,但这个定时器的时间值要小,以此达到瞬间反应的效果。当我们松开键盘时,在keyReleaseEvent中用当前键值ev->key()与数组中的值匹配,如果有就把这个数组值修改成一个无用值,让函数对此信息做不出操作。

        注意,存储键值是添加上,不是顶替,因此也要在存储时做个判断,遍历数组,如果出现无用值,就把它顶替掉,然后立即停止循环。这样做其实有点问题,文末再提出。(菜,求轻点喷)

定义数组,无用值随便取,不要取到键值就行,这里我取-1初始化。

int keys[2] = { -1,-1 };

keyPressEvent与keyReleaseEvent两兄弟

void mainWindow::keyPressEvent(QKeyEvent* ev)
{
    for (int i = 0; i < 2; i++)
    {
        if (keys[i] == -1)
        {
            keys[i] = ev->key();
            break;
        }
    }


    QWidget::keyPressEvent(ev);
}

void mainWindow::keyReleaseEvent(QKeyEvent* ev)
{

    for (int i = 0; i < 2; i++)
    {
        if (ev->key() == keys[i])
        {
            keys[i] = -1;
            break;
        }
    }
    QWidget::keyReleaseEvent(ev);
}

操作函数,第一个if语句里的就是操作了,判断wasd。(这里用switch更好,当时我想着操作很少就用了if语句)

void mainWindow::move()
{
    for (int i = 0; i < 2; i++)
    {
        if (keys[i] == Qt::Key_W)
        {
            if (gamer.Pointy- UpSpeed >= 0)
            {
                gamer.Pointy -= UpSpeed;
                gamer_Label.move(gamer.Pointx, gamer.Pointy);
            }
        }
        if (keys[i] == Qt::Key_S)
        {
            if(gamer.Pointy+157+ DownSpeed <= WindowY)
            {
                gamer.Pointy += DownSpeed;
                gamer_Label.move(gamer.Pointx, gamer.Pointy);
            }
        }
        if (keys[i] == Qt::Key_A)
        {
            if (gamer.Pointx - LeftSpeed > 0)
            {
                gamer.Pointx -= LeftSpeed;
                gamer_Label.move(gamer.Pointx, gamer.Pointy);
            }
            
        }
        if (keys[i] == Qt::Key_D)
        {
            if (gamer.Pointx +251+ RightSpeed < WindowX)
            {
                gamer.Pointx += RightSpeed;
                gamer_Label.move(gamer.Pointx, gamer.Pointy);
            }
            
        }
    }
}

定时器KeysTimer和它的connect函数

    keysTimer.setInterval(4);

    keysTimer.start();    

connect(&keysTimer, &QTimer::timeout, this, [=]()
        {
            move();
        });

        这里说下我之前提到的问题,就是我如果同时按下三个键,再松开一个键,程序有点延迟地反馈给我剩下两个键的操作。原因是,说是同时,其实也有先后,前两个键值已经把数组的无用值顶替,第三个键无法录入但还是按着,但是也会间断性的触发第三个键位的keyPressEvent,当第一个键松开时,就会在间断触发时立即录入,然后执行操作。

        这个问题也好解决,就是扩充数组到3位或n位,但与此同时3位以上或n位以上同时按下松开一个键或多个时也会延迟操作。希望有大佬改进或提出一个新办法来解决。

        文章开头提到的那位大佬文章qt中想判断两个键被按下时_qt如何判断两个键同时按下_yc_Blog的博客-CSDN博客

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值