Qt实战案例(12)——利用Qt实现键盘事件的事件处理

键盘事件的获取是通过重定义QWidget类的keyPressEvent()和keyReleaseEvent()来实现的。

一、项目介绍

通过键盘的上下左右方向键可以控制图标的移动,移动的步进值为网格的大小,如果同时按下Ctrl键,则实现细微移动;若按下Home键,则光标回到界面的左上顶点;若按下End键,则光标达到界面的右下顶点。

二、项目基本配置

新建一个Qt案例,项目名称为“KeyEvent”,基类选择“QWidget”,取消创建UI界面复选框的选中状态,完成项目创建。

三、UI界面设计

无UI界面

四、主程序实现

4.1 资源文件的添加

在编写程序之前,首先需要添加资源文件,资源文件添加十分简单,这里不进行详细介绍,我的代码中将图片1.jpg添加到Qt资源文件res中,利用小锤子图标对其进行构建,构建后的界面如下所示。

在这里插入图片描述

4.2 widget.h头文件

在widget.h的public中声明一个函数drawPix(),重写两个函数keyPressEvent(QKeyEvent *)和paintEvent(QPaintEvent *):

public:
    void drawPix();
    void keyPressEvent(QKeyEvent *);
    void paintEvent(QPaintEvent *);

并且包含两个头文件:

#include<QKeyEvent>
#include<QPaintEvent>

然后定义几个私有变量:

private:
    QPixmap *pix;//作为一个绘图设备,使用双缓冲机制实现图形的绘制
    QImage image;//界面中的小图标
    //图标的左上顶点位置
    int startX=100;
    int startY=100;
    //界面的宽度和高度
    int w;
    int h;
    int step=20; //网格的大小,即移动的步进值

4.3 widget.cpp源文件

widget主函数内进行编写如下代码:

    setWindowTitle("键盘事件");//设置窗口标题
    setAutoFillBackground(true);//设置自动填充背景
    QPalette p=this->palette();//1.定义调色板对象
    p.setColor(QPalette::Window,Qt::white);//2.设置调色板颜色
    setPalette(p);//3.启用调色板对象
    setMinimumSize(512,256);
    setMaximumSize(512,256);
    w=size().width();//获取窗口宽度512
    h=size().height();//获取窗口高度256
    pix=new QPixmap(w,h);
    pix->fill(Qt::white);//填充颜色
    image.load(":/image/1.jpg");//加载图片
    drawPix();
    resize(512,256);//调整尺寸

利用drawPix()函数实现在QPixmap对象上绘制图像:

void Widget::drawPix()
{
    pix->fill(Qt::white);//重新刷新pix对象为白色底色
    QPainter *painter=new QPainter;//创建一个QPainter对象
    QPen pen(Qt::DotLine);//创建QPen对象并设置画笔颜色(点线)
    for (int i=step;i<w;i=i+step) {//按照步进值的间隔绘制纵向的网格线
        painter->begin(pix);
        painter->setPen(pen);
        painter->drawLine(QPoint(i,0),QPoint(i,h));
        painter->end();
    }
    for (int j=step;j<h;j=j+step) {//按照步进值的间隔绘制横向的网格线
        painter->begin(pix);
        painter->setPen(pen);
        painter->drawLine(QPoint(0,j),QPoint(w,j));
        painter->end();
    }
    //在(startX,startY)处绘制image图片
    painter->begin(pix);
    painter->drawImage(QPoint(startX,startY),image);//绘制image图标
    painter->end();

}

重写键盘按下事件keyPressEvent:

//重写键盘按下事件
void Widget::keyPressEvent(QKeyEvent *event)
{
     if(event->modifiers()==Qt::ControlModifier)   //如果按下了Ctrl键
     {
        if(event->key()==Qt::Key_Left){
            startX=(startX-1<0)?startX:startX-1;//左移
        }
        if(event->key()==Qt::Key_Right){
            startX=(startX+1+image.width()>w)?startX:startX+1;//右移
        }
        if(event->key()==Qt::Key_Up){
            startY=(startY-1<0)?startY:startY-1;//上移
        }
        if(event->key()==Qt::Key_Down){
            startY=(startY+1+image.height()>h)?startY:startY+1;//下移
        }

     }
     else   //如果没有按下Ctrl键
     {
        //首先调节图标左上顶点的位置至网格的顶点上
        startX=startX-startX%step;
        startY=startY-startY%step;
        if(event->key()==Qt::Key_Left)
        {
            startX=(startX-step<0)?startX:startX-step;//左移
        }
        if(event->key()==Qt::Key_Right)
        {
            startX=(startX+step+image.width()>w)?startX:startX+step;//右移
        }
        if(event->key()==Qt::Key_Up)
        {
            startY=(startY-step<0)?startY:startY-step;//上移
        }
        if(event->key()==Qt::Key_Down)
        {
            startY=(startY+step+image.height()>h)?startY:startY+step;//下移
        }
        if(event->key()==Qt::Key_Home)
        {
            //如果按下Home键,则将image放在左上角
            startX=0;
            startY=0;
        }
        if(event->key()==Qt::Key_End)
        {
            //如果按下右下角,则将image放在右下角,且需要考虑图标的位置
            startX=w-image.width();
            startY=h-image.height();
        }

     }
    drawPix();//根据调整后的图标位置重新在pix中绘制图像
    update();//更新界面

}

最后,重写绘图事件函数paintEvent:

//重写绘图事件函数
void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter;
    painter.begin(this);
    painter.drawPixmap(QPoint(0,0),*pix);
    painter.end();
}

五、效果演示

显示效果如下:
在这里插入图片描述
完整代码可参考:https://download.csdn.net/download/didi_ya/64003491


ok,以上便是本文的全部内容了,如果对你有所帮助,记得点个赞哟~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wendy_ya

您的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值