您的位置:首页 > 编程语言 > Qt开发

Qt5事件处理及实例

2015-11-23 11:13 337 查看
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));

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: