Qt5事件处理及实例

11.1 鼠标事件及实例
鼠标事件包括鼠标的移动,鼠标键按下、松开、单击、双击等。

运行效果如下:


Qt5事件处理及实例_第1张图片

mouseevent.h
#ifndef MOUSEEVENT_H
#define MOUSEEVENT_H
 
   
#include 
#include 
#include 
#include 
 
   
class MouseEvent : public QMainWindow
{
    Q_OBJECT
 
   
public:
    MouseEvent(QWidget *parent = 0);
    ~MouseEvent();
protected:
    void mouseMoveEvent (QMouseEvent *);
    void mousePressEvent (QMouseEvent *);
    void mouseReleaseEvent (QMouseEvent *);
    void mouseDoubleClickEvent (QMouseEvent *);
private:
    QLabel *statusLabel;
    QLabel *MousePosLabel;
};
 
   
#endif // MOUSEEVENT_H

mouseevent.cpp

#include "mouseevent.h"
 
   
/*
 * statusBar()->addPermanentWidget(statusLabel): 在QMainWindow的状态栏中增加控件
 * this->setMouseTracking (true):设置窗体追踪鼠标。函数setMouseTracking()设置窗体是否追踪鼠标,默认为false,不追踪
 * 在此情况下应该至少有一个鼠标按键按下时响应鼠标移动的事件,
*/
MouseEvent::MouseEvent(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowTitle (tr("鼠标事件"));
    statusLabel = new QLabel(tr("当前位置"));
    statusLabel->setFixedWidth (100);
    MousePosLabel = new QLabel(tr(""));
    MousePosLabel->setFixedWidth (100);
    statusBar()->addPermanentWidget(statusLabel);
    statusBar()->addPermanentWidget(MousePosLabel);
    this->setMouseTracking (true);
    resize(400, 200);
}
 
   
MouseEvent::~MouseEvent()
{
 
   
}
/*
 * 鼠标按下响应函数
 * QMouseEvent类的x()和y()方法可以获得鼠标相对于接收事件的窗体位置,
 * globalX()和globalY()方法可以获得鼠标相对于窗口系统的位置
*/
void MouseEvent::mousePressEvent(QMouseEvent *e)
{
    QString str = "(" + QString::number (e->x ()) + ", " + QString::number (e->y ()) + ")";
 
   
    if(e->button () == Qt::LeftButton)
    {
        statusBar ()->showMessage (tr("左键::") + str);
    }
    else if(e->button () == Qt::RightButton)
    {
        statusBar ()->showMessage (tr("右键:") + str);
    }
    else if(e->button () == Qt::MidButton)
    {
        statusBar ()->showMessage (tr("中键:") + str);
    }
}
/*
 * 鼠标移动响应函数
*/
void MouseEvent::mouseMoveEvent(QMouseEvent *e)
{
    MousePosLabel->setText ("(" + QString::number (e->x ()) + ", " + QString::number (e->y ()) + ")");
}
 
   
void MouseEvent::mouseReleaseEvent(QMouseEvent *e)
{
    QString str = "(" + QString::number (e->x ()) + ", " + QString::number (e->y ()) + ")";
    statusBar ()->showMessage (tr("释放在:") + str);
}
 
   
 
   
void MouseEvent::mouseDoubleClickEvent (QMouseEvent *e)
{
 
   
}

11.2 键盘事件及实例
在图像处理和游戏应用程序中,有时需要通过键盘控制某个对象的移动,此功能可以通过对键盘事件的处理来实现。键盘事件的获取是通过重定义QWidget类的
keyPressEvent()和KeyReleaseEvent()来实现。
通过键盘的上、下、左、右方向可以控制图标的移动,移动的步进值为网络的大小,如果同时按下[Ctrl]键,则实现细微移动:若按下[Home]键,则光标回到界
面的左上点;若按下[End]键,则光标到达界面的右下点。
运行效果

Qt5事件处理及实例_第2张图片
keyevent.h

#ifndef KEYEVENT_H
#define KEYEVENT_H
 
   
#include 
#include 
#include 
 
   
class KeyEvent : public QWidget
{
    Q_OBJECT
 
   
public:
    KeyEvent(QWidget *parent = 0);
    ~KeyEvent();
    void drawPix();
    void keyPressEvent (QKeyEvent *);
    void paintEvent (QPaintEvent *);
private:
    QPixmap *pix;       //作为一个绘图设备,使用双缓冲机制实现图形的绘制
    QImage image;       //界面中间的小图标
    int startx;         //图标的左上顶点位置
    int starty;
    int width;          //界面的宽度和高度
    int height;
    int step;           //网格的大小,及移动的步进值
};
 
   
#endif // KEYEVENT_H

keyevent.cpp

#include "keyevent.h"
#include 
 
   
KeyEvent::KeyEvent(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle (tr("键盘事件"));
    setAutoFillBackground (true);
    QPalette palette = this->palette ();
    palette.setColor (QPalette::Window, Qt::white);
    setPalette (palette);
 
   
    setMinimumSize (525, 265);
    setMaximumSize (525, 265);
    width = size().width ();
    height = size().height ();
 
   
    pix = new QPixmap(width, height);
    pix->fill (Qt::white);
 
   
    image.load ("../image/image.png");
    startx = 100;
    starty = 100;
    step = 20;
    drawPix ();
    resize (525, 265);
}
 
   
KeyEvent::~KeyEvent()
{
 
   
}
 
   
void KeyEvent::drawPix ()
{
    pix->fill (Qt::white);              //重新刷新pix对象为白色底色
    QPainter *painter = new QPainter;   //创建一个QPainter对象
    QPen pen(Qt::DotLine);              //设置画笔的风格,用于绘制网络表格
 
   
    for(int i = step; i  <= 520; i += step)
    {
        for(int j = step; j <= 260; j += step)
        {
            painter->begin (pix);
            painter->setPen (pen);
            painter->drawLine (QPoint(i, 20), QPoint(i, 260));
            painter->drawLine (QPoint(20, j), QPoint(520, j));
            painter->end ();
        }
    }
 
   
    painter->begin (pix);
    /*在pix对象中绘制可移动的小图标*/
    painter->drawImage (QPoint(startx, starty), image);
    painter->end ();
}
 
   
void KeyEvent::keyPressEvent (QKeyEvent *e)
{
    if(e->modifiers () == Qt::ControlModifier)
    {
        if(e->key () == Qt::Key_Left)
        {
            startx = (startx - 1 < 21) ? startx : startx - 1;
        }
        if(e->key () == Qt::Key_Right)
        {
            startx = (startx + 1 + image.width () > width - 5) ? startx : startx + 1;
        }
        if(e->key () == Qt::Key_Up)
        {
            starty = (starty - 1 < 21) ? starty : starty - 1;
        }
        if(e->key () == Qt::Key_Down)
        {
            starty = (starty + 1 + image.width () > height - 5) ? starty : starty + 1;
        }
    }
    else
    {
        /*首先调节图标左上顶点的位置至网络的顶点上*/
        startx = startx - startx % step;
        starty = starty - starty % step;
        if(e->key () == Qt::Key_Left)
        {
            startx = (startx - step < 1) ? startx + 1 : startx - step;
        }
        if(e->key () == Qt::Key_Right)
        {
            startx = (startx + step + image.width () > width - 5) ? startx : startx + step;
        }
        if(e->key () == Qt::Key_Up)
        {
            starty = (starty - step < 1) ? starty + 1 : starty - step;
        }
        if(e->key () == Qt::Key_Down)
        {
            starty = (starty + step + image.width () > height - 5) ? starty : starty + step;
        }
 
   
        if(e->key () == Qt::Key_Home)
        {
            startx = 21;
            starty = 21;
        }
        if(e->key () == Qt::Key_End)
        {
            startx = 520 - image.width ();
            starty = 260 - image.height ();
        }
    }
    drawPix ();         //根据调整后的图标位置重新在pix中绘制图像
    update ();          //触发界面重画
}
 
   
/*
 * 界面重画函数paintEvent(),将pix绘制在界面上。
*/
void KeyEvent::paintEvent (QPaintEvent *p)
{
    QPainter painter;
    painter.begin (this);
    painter.drawPixmap (QPoint(-10, -10), *pix);
    painter.end ();
}
11.3事件过滤及实例
Qt的事件模型中提供的事件过滤器功能使得一个QObject对象可以监视另一个QObject对象中的事件,通过在一个QObject对象中安装事件过滤器,可以在事件到达该对象
前捕获事件,从而起到监视该对象事件的效果。
运行效果如下:
Qt5事件处理及实例_第3张图片

Qt5事件处理及实例_第4张图片
Qt5事件处理及实例_第5张图片
eventfilter.h
#ifndef EVENTFILTER_H
#define EVENTFILTER_H
 
   
#include 
#include 
#include 
#include 
 
   
class EventFilter : public QDialog
{
    Q_OBJECT
 
   
public:
    EventFilter(QWidget *parent = 0);
    ~EventFilter();
public slots:
    bool eventFilter (QObject *, QEvent *);
private:
    QLabel *label1;
    QLabel *label2;
    QLabel *label3;
 
   
    QLabel *stateLabel;
 
   
    QImage Image1;
    QImage Image2;
    QImage Image3;
};
 
   
#endif // EVENTFILTER_H

eventfilter.cpp

#include "eventfilter.h"
#include 
#include 
#include 
#include 
 
   
EventFilter::EventFilter(QWidget *parent)
    : QDialog(parent)
{
    setWindowTitle (tr("事件过滤"));
    label1 = new QLabel;
    Image1.load ("../image3/1.png");
    label1->setAlignment (Qt::AlignHCenter | Qt::AlignVCenter);
    label1->setPixmap (QPixmap::fromImage (Image1));
 
   
    label2 = new QLabel;
    Image2.load ("../image3/2.png");
    label2->setAlignment (Qt::AlignHCenter | Qt::AlignVCenter);
    label2->setPixmap (QPixmap::fromImage (Image2));
 
   
    label3 = new QLabel;
    Image3.load ("../image3/3.png");
    label3->setAlignment (Qt::AlignHCenter | Qt::AlignVCenter);
    label3->setPixmap (QPixmap::fromImage (Image3));
 
   
    stateLabel = new QLabel(tr("鼠标按下标志"));
    stateLabel->setAlignment (Qt::AlignHCenter);
 
   
    QHBoxLayout *HBoxLayout = new QHBoxLayout;
    HBoxLayout->addWidget (label1);
    HBoxLayout->addWidget (label2);
    HBoxLayout->addWidget (label3);
 
   
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
 
   
    mainLayout->addLayout (HBoxLayout);
    mainLayout->addWidget (stateLabel);
    /*为每一个图片安装事件过滤器,指定窗体为监视事件的对象*/
    label1->installEventFilter (this);
    label2->installEventFilter (this);
    label3->installEventFilter (this);
}
 
   
EventFilter::~EventFilter()
{
 
   
}
/*
 * void QObject::installEventFilter
 * (
 *  QObject *filterObj
 * )
 * 参数filterObj是监视事件的对象,此对象可以通过eventFilter()函数接收事件。如果某个事件参数被过滤,即停止正常的
 * 事件响应,则在eventFilter()函数中返回true,否则返回false,QObject的removeEventFilter()可以解除已安装的
 * 事件过滤器。QObject的事件监视函数eventFilter()的具体实现代码
*/
bool EventFilter::eventFilter (QObject *watched, QEvent *event)
{
    //首先判断当前发生事件的对象
    if(watched == label1)
    {
        //判断发生的事件类型
        if(event->type () == QEvent::MouseButtonPress)
        {
            //将事件event转化为鼠标事件
            QMouseEvent *mouseEvent = (QMouseEvent*) event;
            if(mouseEvent->buttons () == Qt::LeftButton)
            {
                stateLabel->setText (tr("左键按下左图片"));
            }
            else if(mouseEvent->buttons () == Qt::MidButton)
            {
                stateLabel->setText (tr("中间按键按下左图片"));
            }
            else if(mouseEvent->buttons () == Qt::RightButton)
            {
                stateLabel->setText (tr("右键按下左图片"));
            }
 
   
            QMatrix matrix;
            matrix.scale (1.8, 1.8);
            QImage newImage = Image1.transformed (matrix);
            label1->setPixmap (QPixmap::fromImage (newImage));
        }
        /*鼠标释放的处理,恢复图片的大小*/
        if(event->type () == QEvent::MouseButtonRelease)
        {
            stateLabel->setText (tr("鼠标释放左图片"));
            label1->setPixmap (QPixmap::fromImage (Image1));
        }
    }
    else if(watched == label2)
    {
        if(event->type () == QEvent::MouseButtonPress)
        {
            QMouseEvent *mouseEvent = (QMouseEvent*)event;
            if(mouseEvent->buttons () == Qt::LeftButton)
            {
                stateLabel->setText (tr("左键按下中间图标"));
            }
            else if(mouseEvent->buttons () == Qt::MidButton)
            {
                stateLabel->setText (tr("中间按键按下中间图片"));
            }
            else if(mouseEvent->buttons () == Qt::RightButton)
            {
                stateLabel->setText (tr("右键按下中间图片"));
            }
 
   
            QMatrix matrix;
            matrix.scale (1.8, 1.8);
            QImage newImage = Image2.transformed (matrix);
            label2->setPixmap (QPixmap::fromImage (newImage));
        }
        if(event->type () == QEvent::MouseButtonRelease)
        {
            stateLabel->setText (tr("鼠标释放中间图标"));
            label2->setPixmap (QPixmap::fromImage (Image2));
        }
    }
    else if(watched == label3)
    {
        if(event->type () == QEvent::MouseButtonPress)
        {
            QMouseEvent *mouseEvent = (QMouseEvent*)event;
            if(mouseEvent->buttons () == Qt::LeftButton)
            {
                stateLabel->setText (tr("左键按下右边图片"));
            }
            else if(mouseEvent->buttons () == Qt::MidButton)
            {
                stateLabel->setText (tr("中间按键按下右边图片"));
            }
            else if(mouseEvent->buttons () == Qt::RightButton)
            {
                stateLabel->setText (tr("右边按键按下右图标"));
            }
            QMatrix matrix;
            matrix.scale (1.8, 1.8);
            QImage newImage = Image3.transformed (matrix);
            label3->setPixmap (QPixmap::fromImage (newImage));
        }
        if(event->type () == QEvent::MouseButtonRelease)
        {
            stateLabel->setText (tr("鼠标释放右边图片"));
            label3->setPixmap (QPixmap::fromImage (Image3));
        }
    }
}

你可能感兴趣的:(Qt5事件处理及实例)