如此这样就能使用上下左右键移动焦点,使用确认键来操作了。
想没想起来,以前的老式非智能机的时代,导航按键不就是 上下左右+确认吗???
上图吧。
上代码吧.
#include "zpage1.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyleSheet("\
QToolButton:focus{background-color:yellow;}\
QCheckBox:focus{background-color:yellow;}\
QRadioButton:focus{background-color:yellow;}");
ZPage1 w;
w.show();
return a.exec();
}
#ifndef ZPAGE1_H
#define ZPAGE1_H
#include <QWidget>
#include <QKeyEvent>
#include <QDebug>
#include <QGridLayout>
#include <QToolButton>
#include <zdialog1.h>
#include <zpage2.h>
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];
ZPage2 *m_page2;
};
#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);
this->m_page2=new ZPage2;
}
ZPage1::~ZPage1()
{
for(qint32 i=0;i<20;i++)
{
delete this->m_btnArray[i];
}
delete this->m_gridLayout;
delete this->m_page2;
}
void ZPage1::ZSlotBtnClicked()
{
QToolButton *btn=qobject_cast<QToolButton*>(sender());
if(btn)
{
qDebug()<<"Button Clicked:"<<btn->text();
if(btn==this->m_btnArray[2])
{
this->m_page2->setGeometry(100,100,400,300);
this->m_page2->show();
}
if(btn==this->m_btnArray[3])
{
ZDialog1 tdia;
tdia.exec();
}
}
}
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;
}
#ifndef ZPAGE2_H
#define ZPAGE2_H
#include <QWidget>
#include <QTextEdit>
#include <QGridLayout>
#include <QToolButton>
#include <QEvent>
#include <QKeyEvent>
#include <QCheckBox>
#include <QRadioButton>
#include <QDebug>
class ZPage2 : public QWidget
{
Q_OBJECT
public:
explicit ZPage2(QWidget *parent = 0);
~ZPage2();
protected:
bool eventFilter(QObject *obj, QEvent *event);
signals:
public slots:
void ZSlotAddSomething();
private:
QTextEdit *m_textEdit;
QToolButton *m_btnAdd;
QToolButton *m_btnClose;
QCheckBox *m_checkBox1;
QCheckBox *m_checkBox2;
QRadioButton *m_radio1;
QRadioButton *m_radio2;
QGridLayout *m_gridLayout;
};
#endif // ZPAGE2_H
#include "zpage2.h"
ZPage2::ZPage2(QWidget *parent) :
QWidget(parent)
{
this->m_textEdit=new QTextEdit;
this->m_textEdit->installEventFilter(this);
this->m_btnAdd=new QToolButton;
this->m_btnAdd->installEventFilter(this);
this->m_btnAdd->setText(tr("Add"));
connect(this->m_btnAdd,SIGNAL(clicked()),this,SLOT(ZSlotAddSomething()));
this->m_btnClose=new QToolButton;
this->m_btnClose->installEventFilter(this);
this->m_btnClose->setText(tr("Close"));
connect(this->m_btnClose,SIGNAL(clicked()),this,SLOT(close()));
this->m_checkBox1=new QCheckBox;
this->m_checkBox1->installEventFilter(this);
this->m_checkBox1->setText(tr("Male"));
this->m_checkBox2=new QCheckBox;
this->m_checkBox2->installEventFilter(this);
this->m_checkBox2->setText(tr("Female"));
this->m_radio1=new QRadioButton;
this->m_radio1->setText(tr("Big"));
this->m_radio1->installEventFilter(this);
this->m_radio2=new QRadioButton;
this->m_radio2->setText(tr("Small"));
this->m_radio2->installEventFilter(this);
this->m_gridLayout=new QGridLayout;
this->m_gridLayout->addWidget(this->m_textEdit,0,0,1,2);
this->m_gridLayout->addWidget(this->m_btnAdd,1,0,1,1);
this->m_gridLayout->addWidget(this->m_btnClose,1,1,1,1);
this->m_gridLayout->addWidget(this->m_checkBox1,2,0,1,1);
this->m_gridLayout->addWidget(this->m_checkBox2,2,1,1,1);
this->m_gridLayout->addWidget(this->m_radio1,3,0,1,1);
this->m_gridLayout->addWidget(this->m_radio2,3,1,1,1);
this->setLayout(this->m_gridLayout);
}
ZPage2::~ZPage2()
{
delete this->m_textEdit;
delete this->m_btnAdd;
delete this->m_btnClose;
delete this->m_checkBox1;
delete this->m_checkBox2;
delete this->m_radio1;
delete this->m_radio2;
delete this->m_gridLayout;
}
bool ZPage2::eventFilter(QObject *obj, QEvent *event)
{
if(event->type()==QEvent::KeyPress)
{
QKeyEvent *tEvent=static_cast<QKeyEvent*>(event);
if(tEvent)
{
//find current focus widget's (x,y).
qint32 tFocusX;
qint32 tFocusY;
bool bFindIt=false;
for(qint32 i=0;i<this->m_gridLayout->rowCount();i++)
{
for(qint32 j=0;j<this->m_gridLayout->columnCount();j++)
{
QLayoutItem *tItem=this->m_gridLayout->itemAtPosition(i,j);
if(!tItem)
{
continue;
}
QWidget *tWidget=tItem->widget();
if(!tWidget || !this->focusWidget())
{
continue;
}
if(tWidget==this->focusWidget())
{
//find current focus widget's (x,y).
tFocusX=i;
tFocusY=j;
bFindIt=true;
break;
}
}
if(bFindIt)
{
//exit the external loop.
break;
}
}
//move focus to next widget.
switch(tEvent->key())
{
case Qt::Key_Left:
if(tFocusY>0)
{
tFocusY--;
}
break;
case Qt::Key_Right:
if(tFocusY<this->m_gridLayout->columnCount()-1)
{
tFocusY++;
}
break;
case Qt::Key_Up:
if(tFocusX>0)
{
tFocusX--;
}
break;
case Qt::Key_Down:
if(tFocusX<this->m_gridLayout->rowCount()-1)
{
tFocusX++;
}
break;
case Qt::Key_Return:
{
qDebug()<<"Key_Return";
QLayoutItem *tItem=this->m_gridLayout->itemAtPosition(tFocusX,tFocusY);
if(tItem)
{
if(tItem->widget())
{
QToolButton *tBtn=qobject_cast<QToolButton*>(tItem->widget());
if(tBtn)
{
emit tBtn->click();
//we handle this event,so return true.
return true;
}
QCheckBox *tCheckBox=qobject_cast<QCheckBox*>(tItem->widget());
if(tCheckBox)
{
qDebug()<<"change checkState";
tCheckBox->setChecked(tCheckBox->checkState()==Qt::Checked?Qt::Unchecked:Qt::Checked);
//we handle this event,so return true.
return true;
}
QRadioButton *tRadio=qobject_cast<QRadioButton*>(tItem->widget());
if(tRadio)
{
tRadio->setChecked(true);
//we handle this event,so return true.
return true;
}
}
}
}
break;
default:
break;
}
//execute cursor here.
QLayoutItem *tItem=this->m_gridLayout->itemAtPosition(tFocusX,tFocusY);
if(tItem)
{
if(tItem->widget())
{
tItem->widget()->setFocus();
//we handle this event,so return true.
return true;
}
}
}
}
return false;
}
void ZPage2::ZSlotAddSomething()
{
this->m_textEdit->append("hello");
}
#ifndef ZDIALOG1_H
#define ZDIALOG1_H
#include <QDialog>
#include <QGridLayout>
#include <QToolButton>
#include <QListWidget>
#include <QKeyEvent>
#include <QDebug>
class ZDialog1 : public QDialog
{
Q_OBJECT
public:
explicit ZDialog1(QWidget *parent = 0);
~ZDialog1();
protected:
bool eventFilter(QObject *obj, QEvent *event);
signals:
public slots:
private:
QListWidget *m_listWidget;
QToolButton *m_btnFirst;
QToolButton *m_btnPrev;
QToolButton *m_btnNext;
QToolButton *m_btnLast;
QToolButton *m_btnReturn;
QGridLayout *m_gridLayout;
QVBoxLayout *m_vLayout;
};
#endif // ZDIALOG1_H
#include "zdialog1.h"
ZDialog1::ZDialog1(QWidget *parent) :
QDialog(parent)
{
//shell.albert
this->m_listWidget=new QListWidget;
this->m_listWidget->setFocusPolicy(Qt::NoFocus);
this->m_listWidget->addItem(tr("Liangdu"));
this->m_listWidget->addItem(tr("SeDu"));
this->m_listWidget->addItem(tr("DuibiDu"));
this->m_btnFirst=new QToolButton;
this->m_btnFirst->setText(tr("First"));
this->m_btnFirst->installEventFilter(this);
this->m_btnPrev=new QToolButton;
this->m_btnPrev->setText(tr("Previous"));
this->m_btnPrev->installEventFilter(this);
this->m_btnNext=new QToolButton;
this->m_btnNext->setText(tr("Next"));
this->m_btnNext->installEventFilter(this);
this->m_btnLast=new QToolButton;
this->m_btnLast->setText(tr("Last"));
this->m_btnLast->installEventFilter(this);
this->m_btnReturn=new QToolButton;
this->m_btnReturn->setText(tr("Return"));
this->m_btnReturn->installEventFilter(this);
connect(this->m_btnReturn,SIGNAL(clicked()),this,SLOT(accept()));
this->m_gridLayout=new QGridLayout;
this->m_gridLayout->addWidget(this->m_btnFirst,0,0);
this->m_gridLayout->addWidget(this->m_btnPrev,0,1);
this->m_gridLayout->addWidget(this->m_btnNext,0,2);
this->m_gridLayout->addWidget(this->m_btnLast,0,3);
this->m_gridLayout->addWidget(this->m_btnReturn,0,4);
this->m_vLayout=new QVBoxLayout;
this->m_vLayout->addWidget(this->m_listWidget);
this->m_vLayout->addLayout(this->m_gridLayout);
this->setLayout(this->m_vLayout);
}
ZDialog1::~ZDialog1()
{
delete this->m_btnFirst;
delete this->m_btnPrev;
delete this->m_btnNext;
delete this->m_btnLast;
delete this->m_btnReturn;
delete this->m_listWidget;
delete this->m_gridLayout;
delete this->m_vLayout;
}
bool ZDialog1::eventFilter(QObject *obj, QEvent *event)
{
#if 0
if(event->type()==QEvent::KeyPress)
{
QKeyEvent *tKeyEvent=static_cast<QKeyEvent*>(event);
switch(tKeyEvent->key())
{
case Qt::Key_Escape:
qDebug()<<"esc key was pressed.";
emit this->m_btnReturn->click();
return true;
break;
default:
break;
}
return true;
}
return false;
#endif
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;
}
奔跑吧,兄弟,告别鼠标的年代开始了,连接好你的物理矩阵按键,写好你的驱动,激动吧。。。。。。。。。。。。。。。。。。。。