Qt键盘事件实现图片在窗口上下左右移动

2022-08-18 19:01:00

本文实例为大家分享了Qt键盘事件实现图片在窗口上下左右移动,供大家参考,具体内容如下

标签(空格分隔): 键盘事件

一、项目内容:

新建桌面应用程序testKeyEvent,类名KeyEvent,基类QWidget,通过重写键盘事件到达操作的键盘的时候窗口中的图片上下左右移动,类似QtCreator设计模式下通过按键摆放部件时的效果。

二、实现细节

    keyevent.h内容:
    #ifndef KEYEVENT_H
    #define KEYEVENT_H
    
    #include <QWidget>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class keyEvent; }
    QT_END_NAMESPACE
    
    class keyEvent : public QWidget
    {
        Q_OBJECT
    
    public:
        keyEvent(QWidget *parent = nullptr);
        ~keyEvent();
        void drawPix();         //自定义成员函数用来在pixmap上绘制网格线和图片
    protected:
    
        void keyPressEvent(QKeyEvent *event) override;      //重写键盘按下事件
        void paintEvent(QPaintEvent *event) override;       //重写绘图事件
    
    private:
        Ui::keyEvent *ui;
        QPixmap *m_pix;
        QImage m_image;
        int m_startX;   //图标顶点的位置
        int m_startY;
        int m_width;    //界面的宽度和高度
        int m_height;
        int m_step;     //图片移动的步长
    
    };
    #endif // KEYEVENT_H
      构造函数:(初始化窗口大小、pximap、加载图片、要显示图片左上角的坐标)
      keyEvent::keyEvent(QWidget *parent)
          : QWidget(parent)
          , ui(new Ui::keyEvent)
      {
          ui->setupUi(this);
          setWindowTitle("键盘事件");
          setAutoFillBackground(true);
          setFixedSize(512,256);
          m_width=size().width();
          m_height=size().height();
      
          m_pix=new QPixmap(m_width,m_height);
          m_pix->fill(Qt::white);
      
          m_image.load("../car.png"); //当前工作目录默认Debug目录下,car.png在上一级目录下
          m_startX=100;
          m_startY=100;
          m_step=20;
          drawPix();
      }
        drawPix():定义Painter对象,并设置画笔(虚线),m_pix作为绘图设备,在上面绘制网格虚线,还有图片的位置信息
        void keyEvent::drawPix()
        {
            m_pix->fill(Qt::white);
            QPainter painter(this);
            QPen pen(Qt::DotLine); //虚线
        
            painter.begin(m_pix);   //m_pix为绘图设备
            painter.setPen(pen);
        
            //按照步长画纵向的网格虚线
            for(int i=m_step;i<m_width;i+=m_step){
                painter.drawLine(QPoint(i,0),QPoint(i,m_height));
        
            }
            //按照步长画横向的网格虚线
            for(int j=m_step;j<m_height;j+=m_step){
                painter.drawLine(QPoint(0,j),QPoint(m_width,j));
            }
            painter.end();
        
            //画图片
            painter.begin(m_pix);
            painter.drawImage(QPoint(m_startX,m_startY),m_image);
            painter.end();
        }
          重写键盘事件

          1、按下Ctrl+方向键一次图片移动一个像素的距离
          2、普通方向键一次移动步长(m_step:20像素)的距离,ui界面下默认一次移动10个像素

          void keyEvent::keyPressEvent(QKeyEvent *event)
          {
              //按下ctrl键移动一个像素
              if(event->modifiers()==Qt::ControlModifier){
                  if(event->key()==Qt::Key_Left){
                      m_startX=(m_startX-1)<0?m_startX:m_startX-1;
                  }else if(event->key()==Qt::Key_Right){
                      m_startX=(m_startX+1+m_image.width())>m_width?m_startX:m_startX+1;
                  }else if(event->key()==Qt::Key_Up){
                      m_startY=(m_startY-1)<0?m_startY:m_startY-1;
                  }else if(event->key()==Qt::Key_Down){
                      m_startY=(m_startY+1+m_image.height())>m_height?m_startY:m_startY+1;
                  }
              }else{
                  //调整图片左上角的位置到网格顶点
                  m_startX=m_startX+m_startX%m_step;
                  m_startY=m_startY+m_startY%m_step;
                  if(event->key()==Qt::Key_Left){
                      m_startX=(m_startX-m_step)<0?m_startX:m_startX-m_step;
                  }else if(event->key()==Qt::Key_Right){
                      m_startX=(m_startX+m_step+m_image.width())>m_width?m_startX:m_startX+m_step;
                  }else if(event->key()==Qt::Key_Up){
                      m_startY=(m_startY-m_step)<0?m_startY:m_startY-m_step;
                  }else if(event->key()==Qt::Key_Down){
                      m_startY=(m_startY+m_step+m_image.height())>m_height?m_startY:m_startY+m_step;
                  }
              }
              drawPix();  //刷新图片的位置
              update();//触发窗口重绘 ,执行paintEvent();
          
          }
            重写QWidget类绘制事件

            绘制事件触发的条件:(查阅Qt帮助文档)

            1、repaint() or update() was invoked,
            2、the widget was obscured and has now been uncovered, or
            3、many other reasons.

            void keyEvent::paintEvent(QPaintEvent *event)
            {
                //定义Qpainter对象,设置窗口为绘图设备,在窗口绘制pixmap
                QPainter painter;
                painter.begin(this);//绘图设备为窗口
                painter.drawPixmap(QPoint(0,0),*m_pix);
                painter.end();
            
            
            }

            三、效果

            可在任意位置移动小车

            以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易采站长站。