最近需要在一个嵌入式设备上使用物理按键跟Qt界面交互操作,
在这种没有鼠标的情况下,写Qt程序就要小心了,有些东东能用,
有些东东不能用,一定提前得有所考虑。
简单的交互最好只使用按钮,复杂点的,因为涉及到焦点的切换。
复杂点的,如果屏幕还要弹出输入法来,就更加麻烦一些了。
上图吧。
使用事件过滤器,将窗体所有部件的事件都集中在父窗体的事件处理函数中来处理,来决定下一个焦点切换到谁身上。
为了方便在上、下、左、右四个方向进行切换,所以使用了QGridLayout.
#ifndef ZPAGE1_H
#define ZPAGE1_H
#include <QWidget>
#include <QKeyEvent>
#include <QDebug>
#include <QGridLayout>
#include <QToolButton>
class ZPage1 : public QWidget
{
Q_OBJECT
public:
ZPage1(QWidget *parent = 0);
~ZPage1();
protected:
bool eventFilter(QObject *obj, QEvent *event);
private slots:
void ZSlotBtnClicked();
private:
QGridLayout *m_gridLayout;
QToolButton *m_btnArray[20];
};
#endif // ZPAGE1_H
#include "zpage1.h"
ZPage1::ZPage1(QWidget *parent)
: QWidget(parent)
{
this->setStyleSheet("QToolButton{width:50px;height:30px;}");
this->m_gridLayout=new QGridLayout;
qint32 tX=0;
qint32 tY=0;
for(qint32 i=0;i<20;i++)
{
this->m_btnArray[i]=new QToolButton;
this->m_btnArray[i]->installEventFilter(this);
this->m_btnArray[i]->setText(QString("%1").arg(i+1));
this->m_gridLayout->addWidget(this->m_btnArray[i],tX,tY);
if(tX++>=5)
{
tY++;
tX=0;
}
connect(this->m_btnArray[i],SIGNAL(clicked()),this,SLOT(ZSlotBtnClicked()));
}
this->setLayout(this->m_gridLayout);
}
ZPage1::~ZPage1()
{
for(qint32 i=0;i<20;i++)
{
delete this->m_btnArray[i];
}
delete this->m_gridLayout;
}
void ZPage1::ZSlotBtnClicked()
{
QToolButton *btn=qobject_cast<QToolButton*>(sender());
if(btn)
{
qDebug()<<"Button Clicked:"<<btn->text();
}
}
bool ZPage1::eventFilter(QObject *obj, QEvent *event)
{
if(event->type()==QEvent::KeyPress)
{
qint32 tCurFocusX;
qint32 tCurFocusY;
for(qint32 i=0;i<this->m_gridLayout->rowCount();i++)
{
bool bFindIt=false;
for(qint32 j=0;j<this->m_gridLayout->columnCount();j++)
{
QLayoutItem *tItem=this->m_gridLayout->itemAtPosition(i,j);
if(!tItem)
{
continue;
}
QWidget *tFocusWidget=tItem->widget();
if(tFocusWidget && tFocusWidget==this->focusWidget())
{
qDebug()<<"oldPos:"<<i<<j;
tCurFocusX=i;
tCurFocusY=j;
bFindIt=true;
break;
}
}
if(bFindIt)
{
break;
}
}
QKeyEvent *tKeyEvent=static_cast<QKeyEvent*>(event);
switch(tKeyEvent->key())
{
//"Return" is the left area Enter key,"Enter" is the right digital area Enter key.
//they are different.
//case Qt::Key_Enter:
case Qt::Key_Return:
{
qDebug()<<"return";
QLayoutItem *tNewItem=this->m_gridLayout->itemAtPosition(tCurFocusX,tCurFocusY);
if(tNewItem)
{
QToolButton *tBtn=qobject_cast<QToolButton*>(tNewItem->widget());
if(tBtn)
{
emit tBtn->click();
return true;
}
}
}
case Qt::Key_Up:
qDebug()<<"up";
if(tCurFocusX>0)
{
tCurFocusX--;
}
break;
case Qt::Key_Down:
qDebug()<<"down";
if(tCurFocusX<this->m_gridLayout->rowCount()-1)
{
tCurFocusX++;
}
break;
case Qt::Key_Left:
qDebug()<<"left";
if(tCurFocusY>0)
{
tCurFocusY--;
}
break;
case Qt::Key_Right:
qDebug()<<"right";
if(tCurFocusY<this->m_gridLayout->columnCount()-1)
{
tCurFocusY++;
}
break;
default:
break;
}
qDebug()<<"newPos:"<<tCurFocusX<<tCurFocusY;
QLayoutItem *tNewItem=this->m_gridLayout->itemAtPosition(tCurFocusX,tCurFocusY);
if(tNewItem)
{
tNewItem->widget()->setFocus();
}
//we already handle this event,so return false.
//this cause qt do not call other event handler.
return true;
}
return false;
}
慢慢看吧,亲们,不过有个小问题要注意,就是PC兼容的键盘上有2个回车键,左边常用区域叫Return,右边数字区域叫Enter,
没错,Qt5是这样编码的。
好了,剩下的工作就是开始我的嵌入式GUI规则了。包括功能实现,以及与按键互动。
1748



被折叠的 条评论
为什么被折叠?



