QT学习_QT常用事件

QT事件

QT常用事件

  1. 事件的概念
  • QT事件驱动的,程序的每个动作都是有某个事件所触发。
  • 事件来源可以分为3种:
    1. Spontaneous events:从系统得到的事件,比如鼠标键盘事件
    2. Posted events(事件循环处理):由Qt、应用程序产生或直接调用QCoreApplication::postEvent();
    3. Sent events(直接处理):由Qt、应用程序产生或直接调用QCoreApplication::sendEvent();
  1. 按键事件和QKeyEvent
  • 当键盘按键被按下时,按键事件会被加入到消息队列中交由事件循环进行处理。
  • 可以通过重写以下函数来让事件循环对某个类的按键进行特殊的处理:
void QWidget::keyPressEvent(QKeyEvent* event);
bool QWidget::event(QEvent* event);//返回true表示结束

QEvent 是所有QT事件的基类,而QKeyEvent是QEvent的派生类,用于描述按键事件。
常用接口如下:

int QKeyEvent::key()	返回按键事件的按键编码
QString QKeyEvent::text()	将按键事件转化为字符串

例子:
label标签中实现键盘输入即时显示
头文件加入:

//头文件加入:
#include 

//Widget类加入:
private:
    Ui::Widget *ui;
    virtual void keyPressEvent(QKeyEvent*);

源文件加入:

void QWidget::keyPressEvent(QKeyEvent* event)
{
	//ctrl+q
	if(event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Q)
	{
		this->close();
		return;
	}
	
	QString text  = ui->label->text();
	if(event->text() == "\b") text.chop(1);
	else text += event->text();
	
	ui->label->setText(text);
}
  1. 鼠标事件和QMouseEvent
  • QT应用程序中,当鼠标被按下、拖动、抬起时,鼠标事件会被加入到消息队列中交由事件循环进行处理。
  • 我们可以通过重写以下函数来对某个类的鼠标事件进行特殊的处理:
void QWidget::mousePressEvent(QMouseEvent * event);
void QWidget::mouseMoveEvent(QMouseEvent * event);
void QWidget::mouseReleaseEvent(QMouseEvent * event);
bool QWidget::event(QEvent* event);

  • QMouseEvent是QEvent的派生类,用于描述鼠标事件。
  • 常用接口如下:
//相对于!!电脑屏幕!!左上角的X坐标(右为正方向)
int QMouseEvent::globalX() 

//相对于电脑屏幕左上角的Y坐标(下为正方向)
int QMouseEvent::globalY()

//相对于!!控件!!左上角的X坐标
int QMouseEvent::x()

//相对于控件左上角的Y坐标
int QMouseEvent::y()

示例:

  • 首先建一个新类myframe 基类为QFrame
  • 然后编写头文件
  • 在界面编辑器里放入frame控件,并将其提升类型为myframe
  • 然后编写源文件
    头文件:
#ifndef MYFRAME_H
#define MYFRAME_H

#include 

class myframe : public QFrame
{
    Q_OBJECT
public:
    explicit myframe(QWidget *parent=0);
protected:
    virtual void mousePressEvent(QMouseEvent *ev);
    virtual void mouseMoveEvent(QMouseEvent *ev);
    virtual void mouseReleaseEvent(QMouseEvent *ev);

signals:

public slots:

};

#endif // MYFRAME_H

源文件:

#include "myframe.h"
#include 
#include 

myframe::myframe(QWidget *parent):QFrame(parent)
{

}

 void myframe::mousePressEvent(QMouseEvent *ev)
{
	//when click show mouse position
    qDebug()<<ev->x()<<","<<ev->y();	//pos in widget
    
   // qDebug()<globalX()<<","<globalY();	//pos in screen
}
 void myframe::mouseMoveEvent(QMouseEvent *ev)
{
}
 void myframe::mouseReleaseEvent(QMouseEvent *ev)
{
}

  1. 绘图事件
  • 当控件由不可见变为可见,或者控件调用了update函数则会多次触发绘图事件。
  • 我们可以通过重写以下函数来对某个类的绘图事件进行特殊的处理:
void QWidget::paintEvent(QPaintEvent *event);

在绘图事件中可以使用QPainter来对控件进行重绘,重用接口如下:

构造函数:
QPainter::QPainter()

绘图前准备工作,device为要绘制的控件对象地址
bool QPainter::begin(QPaintDevice *device)

绘图结束
bool QPainter::end()

示例1:绘制一段线

  • 首先创建画笔类
  • 准备工作
  • 设置线段两端点
  • 画笔画线
  • 绘图结束
#include 

 void myframe::paintEvent(QPaintEvent *ev)
 {
     QPainter painter;
     painter.begin(this);
     //set point
     QPoint start(0,0);
     QPoint end(100,100);
     //draw
     painter.drawLine(start,end);

     painter.end();
 }

示例2:鼠标绘画

  • 在头文件加入成员 点的数组
  • 在每次鼠标点击、抬起时都会将点坐标加入数组
  • 绘图时从0开始依次将点连起来

头文件

#include 
#include 
#include 
using namespace std;

class myframe : public QFrame
{
    Q_OBJECT
private:
    vector<QPoint> points;

源文件

#include "myframe.h"
#include 
#include 
#include 

myframe::myframe(QWidget *parent):QFrame(parent)
{
}

 void myframe::mousePressEvent(QMouseEvent *ev)
{
    QPoint point(ev->x(),ev->y());
    points.push_back(point);
    update();
}
 void myframe::mouseMoveEvent(QMouseEvent *ev)
{
     QPoint point(ev->x(),ev->y());
     points.push_back(point);
     update();
}
 void myframe::mouseReleaseEvent(QMouseEvent *ev)
{
     QPoint point(ev->x(),ev->y());
     points.push_back(point);
     update();
}

 void myframe::paintEvent(QPaintEvent *ev)
 {
     QPainter painter;
     vector<QPoint>::iterator it;
     if(points.size()<=1)return;
     painter.begin(this);
     QPoint start = points[0];
     for(it=points.begin();it!=points.end();it++)
     {
         painter.drawLine(start,*it);
         start = *it;
     }
     painter.end();
 }

QT学习_QT常用事件_第1张图片

QT事件派发机制

  1. QT事件派发机制
    spontaneous Event->消息队列->事件派发
    Posted Event-> 消息队列->事件派发
    sent Event->事件派发
    事件派发->事件过滤器->事件函数(keyPressEvent等)

  2. QT事件过滤器

  • 所有继承自QObject类都可以对事件进行过滤,只需重写以下函数:
bool QObject::eventFilter(QObject *watch, QEvent* event);

watched:产生经过过滤器的事件的对象
event:经过过滤器的事件对象
返回值:过滤的事件是否结束

当类改写过QObject::eventFilter后,该类的对象就可以被安装到其他对象上进行事件过滤,安装的接口如下:

void QObject::installEventFilter(QObject *filterObj);

filterObj: 改写过QObject::eventFilter的对象

示例:创建一个不能输入的输入框

  • 首先创建一个line edit控件
  • 然后创建一个过滤器
  • 使用ev->type()检测到按键事件时则进行过滤
  • 将过滤器安装到当前对象

源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 

mainwindow::mainwindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::mainwindow)
{
    ui->setupUi(this);
    ui->le_input->installEventFilter(this);
}

mainwindow::~mainwindow()
{
    delete ui;
}

bool mainwindow::eventFilter(QObject* watched,QEvent* ev)
{
    if(watched == ui->le_input)
    {
        if(ev->type() == QEvent::KeyPress)
        {
            qDebug()<<"keyPress filter";
            return true;
        }
    }
    return false;
}

你可能感兴趣的:(QT学习)