qt中想判断两个键被按下时

qt的按键事件机制是这样的。
当你按了一个键是会同时触发keyPressEvent和keyReleaseEvent(反复触发)。
在已经按下一个键的情况下,如果按新的键,则前一个键的keyPressEvent,和keyRelease事件不再触发(会在松开按键时触发keyRelease)。但是,我们实际需要的是想要两个键都能触发按下和抬起事件。整理一下思路,不能反复触发事件了,但是前面提到松开按键时也会触发一次keyRelease事件。所以这个时候我们就可以根据这个特性。创建一个对象来保存这些键的状态,按下则设置这个键的状态为1,抬起则设置状态为0。如果两个键同时被按下,则第一个键是少一次释放事件,如果不释放他的状态就会一直是1。有一个坑,就是同时按下的时候,松开后面按下的键keyRelease事件就不会再触发了,直到第一个键松开会再触发一次。所以我们不能在keyRelease事件里面处理逻辑而是用一个定时器。下面是一个代码片段提供一些思路pressKey可以根据自己的需要去实现

void MainWindow::keyPressEvent(QEvent *e)
{
 	 QKeyEvent *keyEvent=static_cast<QKeyEvent *>(e);
	 switch(keyEvent->key()){
			case  Qt::Key_Q:{
		  		 pressKey->key1=1;//设置按键1为按下状态
		 	 	 break;
			}
			case  Qt::Key_W:
			{
		 	  	 pressKey->key2=1;//设置按键2为按下状态
			     break;
			}
	}
    if(pressKey->haveKeyDown()&&!m_pTimer->isActive())//如果计时器处于停止状态且有一个键已经被按下(总数>1)则开启计时器
    {
        m_pTimer->start(TIMER_TIMEOUT); // 重复间隔 REPEAT_RATE = 300 毫秒
    }
    return QWidget::keyPressEvent(keyEvent);
}
void MainWindow::keyReleaseEvent(QEvent *e)
{
    QKeyEvent *keyEvent=static_cast<QKeyEvent *>(e);
    switch(keyEvent->key()){
			case  Qt::Key_Q:
			{
				   pressKey->key1=0;
			 	   break;
			}
			case  Qt::Key_W:
			{
				  pressKey->key2=0;
			 	  break;
			}
	}//恢复按键的状态
	 if(m_pTimer->isActive()&&!pressKey->haveKeyDown())
     {
               m_pTimer->stop(); // 如果没有键按下停止计时器。
     }
     e->accept();
    return QWidget::keyReleaseEvent(keyEvent);
}
bool MainWindow::event(QEvent *e)
{
    if(e->type()==QEvent::KeyPress)
    {
        keyPressEvent(e);//键盘按下事件
    }
    if(e->type()==QEvent::KeyRelease)
    {
        keyReleaseEvent(e);//键盘抬起事件
        return true;//阻止事件被分发
    }
    return QMainWindow::event(e);//将键盘事件分发下去
}

void MainWindow::handleKeyDown(){
   if( pressKey->key1==1)
    {
       qDebug()<<"you press a q";//处理自己的事情
    }
    if(pressKey->key2==1)
    {
       qDebug()<<"you press a w";//处理自己的事情
    }
}
void MainWindow::initKeyNumber()
{
    pressKey->key1=0;
    pressKey->key2=0;
}

如果想要判断更多的按键同时按下可以在这个的基础上扩展

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值