Qt编程-day04

事件

示例程序地址
事件分发机制
在这里插入图片描述 当某个事件(鼠标、键盘)发生的时候,窗口就会收到这个事件,并且调用相应的事件处理函数,事件处理函数的命名都是以Event结尾的。

事件先会到达窗口的event函数 , event函数 返回值:true表示该事件得到处理,如果是false,没被处理,事件会继续传递到父窗口通过判断QEvent 参数的类型得知事件的类型后,调用相应的事件处理函数。
//判断event的类型
if(e->type()==QEvent::MouseMove)
{
this->mouseMoveEvent(static_cast<QMouseEvent *>(e));
return true;
}
//其他没有被处理的事件,就使用父类的event
return QLabel::event(e);

鼠标事件

mousePressEvnet,mouseReleseEvent,mouseMoveEvent

mousePressEvnet
通过获取鼠标事件处理函数的参数,获取它的坐标和点击了哪个按键
//获取坐标
int x = ev->x();
int y = ev->y();
//获取鼠标按键
Qt::MouseButton btn = ev->button();

mouseMoveEvent
//获取鼠标按键,这里要使用buttons,获取的鼠标按钮的枚举值按位或的一个值
Qt::MouseButtons btns = ev->buttons();
//通过按位与的方式来提取按了哪个按键
if(btns & Qt::LeftButton)
{
strButton += “LeftButton;”;
}
默认情况下,窗口不会主动跟踪鼠标
只有当某个鼠标按键按下的情况下才开始跟踪
如果想一开始跟踪,就要使用以下函数
this->setMouseTracking(true);

事件过滤器
1 窗口调用installEventFilter来安装一个事件过滤器
2 参数是一个事件过滤器对象QObject,该对象的类要重写eventFilter的函数
事件过滤的时候,事件会先到达事件过滤器的eventFilter函数
对象可以使用自己作为自己的过滤器
返回值:true表示拦截,false表示不拦截,不拦截情况下事件会继续的到达窗口

bool MyLabel::eventFilter(QObject *watched, QEvent *event)
{
	if(event->type()==QEvent::MouseMove)
	{
		//返回true 表示拦截该事件
		return true;
	}
	return false;
}

mylabel1.h

protected:
    //重写鼠标案件处理函数
    void mousePressEvent(QMouseEvent *ev);
    //重写鼠标移动的处理函数
    void mouseMoveEvent(QMouseEvent *ev);
    //重写鼠标释放的处理函数
    void mouseReleaseEvent(QMouseEvent *ev);
    //重写事件分发器
    bool event(QEvent *e);
    //重写对象过滤器eventFilter
    bool eventFilter(QObject *watched, QEvent *event);

mylabel1.cpp

#include "mylabel1.h"
#include <QMouseEvent>
#include <QDebug>
mylabel1::mylabel1(QWidget *parent) : QLabel(parent)
{
    //默认情况下,窗口不糊主动跟踪鼠标
    //只有当鼠标按键按下的情况才开始跟踪
    //如果想一开始就跟踪,就要使用以下函数
    this->setMouseTracking(true);

    //事件过滤器的使用
    //1、窗口调用installEventFilter来安装一个事件过滤器
    //2 参数是一个事件过滤器对象QObject ,该对象的类要重写eventFilter的函数
    //事件过滤的时候,事件会先到达事件过滤器的eventFilter函数
    //返回值:true表示拦截,false表示不拦截,不拦截情况下事件会继续到达窗口

    this->installEventFilter(this);
}

void mylabel1::mousePressEvent(QMouseEvent *ev)
{
    //输出鼠标事件一些信息
    //获取坐标
    int x = ev->x();
    int y = ev->y();

    //获取鼠标按钮
    Qt::MouseButton btn = ev->button();
    QString strButton = "";
    if(btn == Qt::LeftButton)
    {
        strButton = "LeftButton";
    }
    if(btn == Qt::RightButton)
    {
        strButton = "RightButton";
    }
    if(btn == Qt::MidButton)
    {
        strButton = "MidButton";
    }
    //label可以显示html
    QString str = QString("<h1><center>press[%1,%2][%3]</center></h1>").arg(x).arg(y).arg(strButton);
    this->setText(str);
}

void mylabel1::mouseMoveEvent(QMouseEvent *ev)
{
    //输出鼠标事件一些信息
    //获取坐标
    int x = ev->x();
    int y = ev->y();

    //获取鼠标按钮
    Qt::MouseButtons btns = ev->buttons();
    QString strButton = "";
    if(btns & Qt::LeftButton)
    {
        strButton += "LeftButton;";
    }
    if(btns & Qt::RightButton)
    {
        strButton += "RightButton;";
    }
    if(btns & Qt::MidButton)
    {
        strButton += "MidButton";
    }
    //label可以显示html
    QString str = QString("<h1><center>move[%1,%2][%3]</center></h1>").arg(x).arg(y).arg(strButton);
    this->setText(str);
}

void mylabel1::mouseReleaseEvent(QMouseEvent *ev)
{
    qDebug()<<"鼠标松开了";
}

bool mylabel1::event(QEvent *e)
{
    //返回值:true表示该事件得到处理,如果时false,没有被处理,事件会继续传递到父窗口
    //QEvent就是所有Event类的父类
    //判断event的类型
    if(e->type() == QEvent::MouseMove)
    {
        this->mouseMoveEvent(static_cast<QMouseEvent *>(e));
        return true;
    }
    return QLabel::event(e);
}

bool mylabel1::eventFilter(QObject *watched, QEvent *event)
{
    if(event->type() == QEvent::MouseMove)//拦截鼠标移动按键
    {
        //返回true,表示拦截
        return true;
    }
    return false;
}

定时器事件
闹钟就是定时器,闹钟响了就是定时器事件
timerEvent

通过startTimer来启动一个定时器,参数是毫秒,每隔相应的时间就会触发一个定时器事件
返回值就是定时器的id

通过killTimer来杀死一个定时,参数就是定时器的id

timerEvent定时器事件处理函数中通过event参数获取到当前事件是哪个定时器发出的,event->timerId()

另一种定时器
使用QTimer 的方式创建定时器
通过关注信号 timeout 来接受定时器到时间的信号
通过start 来启动定时器,参数是信号触发间隔的毫秒
通过stop来停止定时器

定时器代码:
widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTimer>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    //定时器id
    int mTimeId;
    //定时器
    QTimer *mTimer;

protected:
    void timerEvent(QTimerEvent *event);
private slots:
    void on_pushButton_start_clicked();
    void on_pushButton_stop_clicked();
    void on_pushButton_start_3_clicked();
    void on_pushButton_stop_3_clicked();
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QTimer>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //创建定时器
    //startTimer(1000);
}

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

void Widget::timerEvent(QTimerEvent *event)
{
    static int num = 1;
    this->ui->lcdNumber->display(num++);
}

void Widget::on_pushButton_start_clicked()
{
    //创建定时器 设置1秒一次
    this->mTimeId = startTimer(1000);
}

void Widget::on_pushButton_stop_clicked()
{
    //停止定时器
    killTimer(mTimeId);
}

void Widget::on_pushButton_start_3_clicked()
{
    mTimer = new QTimer(this);
    connect(mTimer,&QTimer::timeout,[=](){
        static int num = 1;
        this->ui->lcdNumber_3->display(num++);
    });
    mTimer->start(10);
}

void Widget::on_pushButton_stop_3_clicked()
{
    mTimer->stop();

}

重新画按钮
1 什么时候画
绘图事件:窗口需要重新显示的时候,就会收到一个绘图事件 paintEvent
收到绘图事件之后,窗口就要将自己画出来

2 怎么画
画画的人 —— QPainter
画笔 —— QPen
画布 —— QPaintDevice
QPainter ( 参数是绘图设备 ,this表示在窗口上绘图)
drawLine 划线 , 两点成一线,参数就是两个点的坐标
drawRect 矩形 , 参数是 左上角的点和 宽和高
drawEllips 画椭圆 , 参数是 左上角的点和 宽和高 ,另一种方式就是 圆心 + rx + ry

设置画家的画笔
setPen ( QPen) ,画笔可以设置颜色和风格
设置画家的画刷
setBrush(QBrush) , 填充封闭的图形, 也可以设置颜色 ,默认情况下,画刷不填充,还得设置风格

搬动画家
translate ( x, y) 将画家移动到某个坐标开始画画

手动触发绘图事件
使用两个函数
repaint : 会马上触发绘图事件
update : update做了一些优化 ,比如多次调用只会触发一次事件,建议使用update
注意:不要在paintEvent处理函数中再触发绘图事件,会导致无限循环

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QFileDialog>
#include <QTextCodec>
#include <QFileInfo>
#include <QDebug>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //写文件
    QFile file("F:\\test20.txt");
    file.open(QIODevice::WriteOnly);
    file.write("hello");
    file.close();
}

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

void Widget::on_pushButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,"打开一个文件","","ALL(*.*)");
    //对fileName做判断,如果没有选择文件,那么就是一个空串
    if(fileName.isEmpty())
    {
        return;
    }
    else {
        //选择了文件,将文件名显示到lineEdit
        this->ui->lineEdit->setText(fileName);
    }

    //使用qfile来读取文件
    QFile file(fileName);
    //打开文件  以只读方式打开
    file.open(QIODevice::ReadOnly);

    //读取文件内容
    //将所有内容全部读取出来
    //QByteArray arry = file.readAll();
    //单行读取
    QByteArray arry;
    do{
        arry += file.readLine();
    }while(!file.atEnd());

    //使用gbk编码
    QTextCodec *codec = QTextCodec::codecForName("gbk");

    //将arry转换成QString
    QString content = codec->toUnicode(arry);

    //输出到edit上
    this->ui->plainTextEdit->setPlainText(content);

    //获取文件信息
    QFileInfo info(fileName);
    qDebug()<<"文件全名:"<<info.fileName();
    qDebug()<<"baseName:"<<info.baseName();
    qDebug()<<"路径:"<<info.path();
    qDebug()<<"文件是否为目录:"<<info.isDir();
    //关闭文件
    file.close();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值