1. 程式人生 > >Qt5事件處理及例項

Qt5事件處理及例項

11.1 滑鼠事件及例項 滑鼠事件包括滑鼠的移動,滑鼠鍵按下、鬆開、單擊、雙擊等。 執行效果如下:
mouseevent.h
#ifndefMOUSEEVENT_H
#defineMOUSEEVENT_H
#include<QMainWindow>
#include<QLabel>
#include<QMouseEvent>
#include<QStatusBar>
classMouseEvent:publicQMainWindow
{
Q_OBJECT
public:
MouseEvent(QWidget*parent=0);
~MouseEvent();
protected:
voidmouseMoveEvent(QMouseEvent
*);
voidmousePressEvent(QMouseEvent*);
voidmouseReleaseEvent(QMouseEvent*);
voidmouseDoubleClickEvent(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=newQLabel(tr("當前位置"));
statusLabel->setFixedWidth(100);
MousePosLabel=newQLabel
(tr(""));
MousePosLabel->setFixedWidth(100);
statusBar()->addPermanentWidget(statusLabel);
statusBar()->addPermanentWidget(MousePosLabel);
this->setMouseTracking(true);
resize(400,200);
}
MouseEvent::~MouseEvent()
{
}
/*
*滑鼠按下響應函式
*QMouseEvent類的x()和y()方法可以獲得滑鼠相對於接收事件的窗體位置,
*globalX()和globalY()方法可以獲得滑鼠相對於視窗系統的位置
*/
voidMouseEvent::mousePressEvent(QMouseEvent*e)
{
QStringstr="("+QString::number(e->x())+","+QString::number(e->y())+")";
if(e->button()==Qt::LeftButton)
{
statusBar()->showMessage(tr("左鍵::")+str);
}
elseif(e->button()==Qt::RightButton)
{
statusBar()->showMessage(tr("右鍵:")+str);
}
elseif(e->button()==Qt::MidButton)
{
statusBar()->showMessage(tr("中鍵:")+str);
}
}
/*
*滑鼠移動響應函式
*/
voidMouseEvent::mouseMoveEvent(QMouseEvent*e)
{
MousePosLabel->setText("("+QString::number(e->x())+","+QString::number(e->y())+")");
}
voidMouseEvent::mouseReleaseEvent(QMouseEvent*e)
{
QStringstr="("+QString::number(e->x())+","+QString::number(e->y())+")";
statusBar()->showMessage(tr("釋放在:")+str);
}
voidMouseEvent::mouseDoubleClickEvent(QMouseEvent*e)
{
}
11.2 鍵盤事件及例項 在影象處理和遊戲應用程式中,有時需要通過鍵盤控制某個物件的移動,此功能可以通過對鍵盤事件的處理來實現。鍵盤事件的獲取是通過重定義QWidget類的 keyPressEvent()和KeyReleaseEvent()來實現。 通過鍵盤的上、下、左、右方向可以控制圖示的移動,移動的步進值為網路的大小,如果同時按下[Ctrl]鍵,則實現細微移動:若按下[Home]鍵,則游標回到界 面的左上點;若按下[End]鍵,則游標到達介面的右下點。 執行效果
keyevent.h
#ifndefKEYEVENT_H
#defineKEYEVENT_H
#include<QWidget>
#include<QKeyEvent>
#include<QPaintEvent>
classKeyEvent:publicQWidget
{
Q_OBJECT
public:
KeyEvent(QWidget*parent=0);
~KeyEvent();
voiddrawPix();
voidkeyPressEvent(QKeyEvent*);
voidpaintEvent(QPaintEvent*);
private:
QPixmap*pix;//作為一個繪圖裝置,使用雙緩衝機制實現圖形的繪製
QImageimage;//介面中間的小圖示
intstartx;//圖示的左上頂點位置
intstarty;
intwidth;//介面的寬度和高度
intheight;
intstep;//網格的大小,及移動的步進值
};
#endif//KEYEVENT_H
keyevent.cpp
#include"keyevent.h"
#include<QPainter>
KeyEvent::KeyEvent(QWidget*parent)
:QWidget(parent)
{
setWindowTitle(tr("鍵盤事件"));
setAutoFillBackground(true);
QPalettepalette=this->palette();
palette.setColor(QPalette::Window,Qt::white);
setPalette(palette);
setMinimumSize(525,265);
setMaximumSize(525,265);
width=size().width();
height=size().height();
pix=newQPixmap(width,height);
pix->fill(Qt::white);
image.load("../image/image.png");
startx=100;
starty=100;
step=20;
drawPix();
resize(525,265);
}
KeyEvent::~KeyEvent()
{
}
voidKeyEvent::drawPix()
{
pix->fill(Qt::white);//重新重新整理pix物件為白色底色
QPainter*painter=newQPainter;//建立一個QPainter物件
QPenpen(Qt::DotLine);//設定畫筆的風格,用於繪製網路表格
for(inti=step;i<=520;i+=step)
{
for(intj=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();
}
voidKeyEvent::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繪製在介面上。
*/
voidKeyEvent::paintEvent(QPaintEvent*p)
{
QPainterpainter;
painter.begin(this);
painter.drawPixmap(QPoint(-10,-10),*pix);
painter.end();
}
11.3事件過濾及例項 Qt的事件模型中提供的事件過濾器功能使得一個QObject物件可以監視另一個QObject物件中的事件,通過在一個QObject物件中安裝事件過濾器,可以在事件到達該物件 前捕獲事件,從而起到監視該物件事件的效果。 執行效果如下:


eventfilter.h
#ifndefEVENTFILTER_H
#defineEVENTFILTER_H
#include<QDialog>
#include<QLabel>
#include<QImage>
#include<QEvent>
classEventFilter:publicQDialog
{
Q_OBJECT
public:
EventFilter(QWidget*parent=0);
~EventFilter();
publicslots:
booleventFilter(QObject*,QEvent*);
private:
QLabel*label1;
QLabel*label2;
QLabel*label3;
QLabel*stateLabel;
QImageImage1;
QImageImage2;
QImageImage3;
};
#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=newQLabel;
Image1.load("../image3/1.png");
label1->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
label1->setPixmap(QPixmap::fromImage(Image1));
label2=newQLabel;
Image2.load("../image3/2.png");
label2->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
label2->setPixmap(QPixmap::fromImage(Image2));
label3=newQLabel;
Image3.load("../image3/3.png");
label3->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
label3->setPixmap(QPixmap::fromImage(Image3));
stateLabel=newQLabel(tr("滑鼠按下標誌"));
stateLabel->setAlignment(Qt::AlignHCenter);
QHBoxLayout*HBoxLayout=newQHBoxLayout;
HBoxLayout->addWidget(label1);
HBoxLayout->addWidget(label2);
HBoxLayout->addWidget(label3);
QVBoxLayout*mainLayout=newQVBoxLayout(this);
mainLayout->addLayout(HBoxLayout);
mainLayout->addWidget(stateLabel);
/*為每一個圖片安裝事件過濾器,指定窗體為監視事件的物件*/
label1->installEventFilter(this);
label2->installEventFilter(this);
label3->installEventFilter(this);
}
EventFilter::~EventFilter()
{
}
/*
*voidQObject::installEventFilter
*(
*QObject*filterObj
*)
*引數filterObj是監視事件的物件,此物件可以通過eventFilter()函式接收事件。如果某個事件引數被過濾,即停止正常的
*事件響應,則在eventFilter()函式中返回true,否則返回false,QObject的removeEventFilter()可以解除已安裝的
*事件過濾器。QObject的事件監視函式eventFilter()的具體實現程式碼
*/
boolEventFilter::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("左鍵按下左圖片"));
}
elseif(mouseEvent->buttons()==Qt::MidButton)
{
stateLabel->setText(tr("中間按鍵按下左圖片"));
}
elseif(mouseEvent->buttons()==Qt::RightButton)
{
stateLabel->setText(tr("右鍵按下左圖片"));
}
QMatrixmatrix;
matrix.scale(1.8,1.8);
QImagenewImage=Image1.transformed(matrix);
label1->setPixmap(QPixmap::fromImage(newImage));
}
/*滑鼠釋放的處理,恢復圖片的大小*/
if(event->type()==QEvent::MouseButtonRelease)
{
stateLabel->setText(tr("滑鼠釋放左圖片"));
label1->setPixmap(QPixmap::fromImage(Image1));
}
}
elseif(watched==label2)
{
if(event->type()==QEvent::MouseButtonPress)
{
QMouseEvent*mouseEvent=(QMouseEvent*)event;
if(mouseEvent->buttons()==Qt::LeftButton)
{
stateLabel->setText(tr("左鍵按下中間圖示"));
}
elseif(mouseEvent->buttons()==Qt::MidButton)
{
stateLabel->setText(tr("中間按鍵按下中間圖片"));
}
elseif(mouseEvent->buttons()==Qt::RightButton)
{
stateLabel->setText(tr("右鍵按下中間圖片"));
}
QMatrixmatrix;
matrix.scale(1.8,1.8);
QImagenewImage=Image2.transformed(matrix);
label2->setPixmap(QPixmap::fromImage(newImage));
}
if(event->type()==QEvent::MouseButtonRelease)
{
stateLabel->setText(tr("滑鼠釋放中間圖示"));
label2->setPixmap(QPixmap::fromImage(Image2));
}
}
elseif(watched==label3)
{
if(event->type()==QEvent::MouseButtonPress)
{
QMouseEvent*mouseEvent=(QMouseEvent*)event;
if(mouseEvent->buttons()==Qt::LeftButton)
{
stateLabel->setText(tr("左鍵按下右邊圖片"));
}
elseif(mouseEvent->buttons()==Qt::MidButton)
{
stateLabel->setText(tr("中間按鍵按下右邊圖片"));
}
elseif(mouseEvent->buttons()==Qt::RightButton)
{
stateLabel->setText(tr("右邊按鍵按下右圖示"));
}
QMatrixmatrix;
matrix.scale(1.8,1.8);
QImagenewImage=Image3.transformed(matrix);
label3->setPixmap(QPixmap::fromImage(newImage));
}
if(event->type()==QEvent::MouseButtonRelease)
{
stateLabel->setText(tr("滑鼠釋放右邊圖片"));
label3->setPixmap(QPixmap::fromImage(Image3));
}
}
}