Qt5事件处理及实例

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

运行效果如下:




mouseevent.h
#ifndef MOUSEEVENT_H
#define MOUSEEVENT_H
 
 
#include <QMainWindow>
#include <QLabel>
#include <QMouseEvent>
#include <QStatusBar>
 
 
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]键,则光标到达界面的右下点。
运行效果


keyevent.h

#ifndef KEYEVENT_H
#define KEYEVENT_H
 
 
#include <QWidget>
#include <QKeyEvent>
#include <QPaintEvent>
 
 
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 <QPainter>
 
 
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对象中安装事件过滤器,可以在事件到达该对象
前捕获事件,从而起到监视该对象事件的效果。
运行效果如下:




eventfilter.h
#ifndef EVENTFILTER_H
#define EVENTFILTER_H
 
 
#include <QDialog>
#include <QLabel>
#include <QImage>
#include <QEvent>
 
 
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 <QHBoxLayout>
#include <QVBoxLayout>
#include <QMouseEvent>
#include <QMatrix>
 
 
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));
        }
    }
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Qt5是一种跨平台的C++应用程序框架,可以用于开发各种类型的应用程序。qt5开发及实例pdf是一种学习Qt5框架的材料,可以帮助开发人员更好地了解Qt5框架的基础知识和使用方法。 qt5开发及实例pdf包含了Qt5应用程序开发的各种方面,从Qt5的基础概念到GUI和应用程序开发。在这个PDF中,你会学习如何使用Qt Creator,Qt中的Qt Widgets和QML等API来创建界面和应用程序。你也会学习如何使用事件和信号与槽机制来实现各种功能。此外,还会介绍Qt5中支持的媒体、网络、数据库、图像处理、WebSockets和本地文件系统等模块。 此外,qt5开发及实例pdf也包含了一些实际的示例,例如创建一个简单的文本编译器,使用Qt5绘制二维图形以及在Qt5中使用SQLite数据库等。这些示例可以帮助开发人员更好地理解Qt5的应用和功能。 总之,qt5开发及实例pdf可以帮助开发人员更加深入地学习Qt5框架,提供了一个全面而系统的介绍,使他们能够更加高效、灵活地使用Qt5来开发应用程序。 ### 回答2: 《Qt5开发及实例》是一本关于Qt5开发的书籍。Qt是一个跨平台的应用程序框架,它提供了一套友好的GUI和多媒体功能,使得开发人员可以快速创建高效的应用程序。 该书的作者是史荣华,他详细介绍了如何使用Qt5开发GUI应用程序,并提供了大量实例来帮助读者学习和掌握Qt的基本概念和技术。 该书分为四个部分,第一部分介绍了Qt的基础知识,包括Qt的安装和配置、Qt Creator的使用、Qt对象模型等。第二部分详细介绍了Qt的GUI编程,包括窗口、控件、布局、事件处理等。第三部分介绍了Qt的数据库编程,包括MySQL、SQLite等数据库的使用。第四部分是以实例为案例,讲解如何使用Qt实现一些常见的应用程序,例如多媒体播放器、电子邮件客户端、文本编辑器等。 总体来说,该书内容全面详实,适合初学者和有一定经验的开发人员阅读。对于想要学习Qt5开发的人来说,这本书是一本非常好的入门教材。 ### 回答3: QT5开发是一种面向对象的编程语言,它提供了一系列丰富的工具和功能,便于程序员进行开发工作。对于需要学习和了解QT5开发的开发者来说,一本非常实用的工具是《QT5开发及实例》PDF。 该PDF文档包含了关于QT5开发的详细介绍和实例,可以帮助开发者快速掌握这种编程语言。例如,它会介绍QT5开发的基础知识和概念,以及如何使用QT5创建GUI应用程序和窗口。 此外,该文档还包含各种实用的例子,例如如何使用QT5开发一个简单的计算器应用程序或一个涂鸦板应用程序。这些实例不仅可以让开发者更好地理解QT5的各种概念和工具,还可以帮助他们快速地构建自己的应用程序。 总的来说,《QT5开发及实例》PDF是一个非常实用的工具,不仅可以帮助有经验的开发者学习QT5开发,还可以帮助新手开发者入门。它清晰明了地讲解了QT5的工具和概念,并提供了各种实用的例子,使开发者可以快速学习和掌握这种编程语言。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值