勇哥的VC++应用框架学习之QT(6) Qt的事件、定时器


本篇演示了下面的内容:

  • QLabel中鼠标常用事件

  • 定时器的二种实现方式

  • 负责事件分发的event事件

  • 负责事件过滤的eventFilter



下面的演示代码中,界面上第一个label是一个提升为Mylabel类的自定义控件.

其它的是普通的label

image.png

image.png


MyLable.h

#pragma once
#pragma execution_character_set("utf-8")
#include "qlabel.h"

class MyLable : public QLabel
{
	Q_OBJECT

public:
	MyLable(QWidget *parent);
	~MyLable();
	//这两个是继承自QWidget类都有的事件
	void enterEvent(QEvent *);
	void leaveEvent(QEvent *);
	
	//下面三个是继承自QLable类的独有事件
	void mouseMoveEvent(QMouseEvent *ev);
	void mousePressEvent(QMouseEvent *ev);
	void mouseReleaseEvent(QMouseEvent *ev);

	bool event(QEvent *ev);

};


MyLable.cpp

#include "MyLable.h"
#include <qdebug.h>
#include <QMouseEvent>


MyLable::MyLable(QWidget *parent): QLabel(parent)
{
}

MyLable::~MyLable()
{
}

void MyLable::enterEvent(QEvent *e){
	qDebug() << "鼠标进入了...";
}

void MyLable::leaveEvent(QEvent *e){
	qDebug() << "鼠标离开了...";
}


void MyLable::mouseMoveEvent(QMouseEvent *ev){
	//持续状态,要用buttons 用与操作符进行判断
	//大家可以试试不要这个if的对比效果
	if (ev->buttons() & Qt::LeftButton){
		//按下左键的情况下才会输出下面信息
		QString msg = QString("鼠标移动了... x=%1,y=%2").arg(ev->x()).arg(ev->y());
		qDebug() << msg;
	}
}
void MyLable::mousePressEvent(QMouseEvent *ev){
	if (ev->button() == Qt::LeftButton){
		qDebug() << "鼠标按下了...";
	}
}
void MyLable::mouseReleaseEvent(QMouseEvent *ev){
	if (ev->button() == Qt::LeftButton){
		qDebug() << "鼠标松开了...";
	}
}

//event事件负责全部事件的分发工作,勇哥理解相当于消息环境中的case处理
bool MyLable::event(QEvent *ev){
	if (ev->type() == QEvent::MouseButtonPress){
		QMouseEvent * e = static_cast<QMouseEvent *>(ev);
		QString str = QString("Event: 鼠标按下 x=%1 y=%2").arg(e->x()).arg(e->y());
		qDebug() << str;
		//只有鼠标扫下事件自己处理
		return true;
	}
	//其它事件交给父类处理
	return QLabel::event(ev);
}

QtForOpencv.h

#pragma once
#pragma execution_character_set("utf-8")
#include <QtWidgets/QWidget>
#include "ui_QtForOpencv.h"
#include <QLabel>

class QtForOpencv : public QWidget
{
	Q_OBJECT

public:
	QtForOpencv(QWidget *parent = Q_NULLPTR);
	void timerEvent(QTimerEvent *e);
	bool eventFilter(QObject *, QEvent *);

private:
	Ui::QtForOpencvClass ui;
	int id1=0;
	int id2=0;
public:
	QLabel* imgLabel;
};

QtForOpencv.cpp

#include "QtForOpencv.h"
#include <opencv2\opencv.hpp>
#include <opencv2\core.hpp>
#include <opencv2\imgcodecs.hpp>
#include <opencv2\imgproc.hpp>
#include <qtimer.h>
#include <qevent.h>
#include <qdebug.h>

using namespace cv;
using namespace std;
QtForOpencv::QtForOpencv(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	
	id1=startTimer(1000);
	id2 = startTimer(200);

	//第二种订时器的办法
	QTimer * t1 = new QTimer(this);
	t1->start(500); 
	connect(t1, &QTimer::timeout, [=](){
		static long num = 0;
		ui.labTimer3->setText(QString::number(num++));
	});

	//点按钮后暂t1
	connect(ui.btnStop, &QPushButton::clicked, [=]{
		t1->stop();
	});

	//事件过滤器用法
	//步骤1:先给控件安装过滤器
	ui.label->installEventFilter(this);
	//步骤2:重写eventFilter事件

	waitKey(0);

}

void QtForOpencv::timerEvent(QTimerEvent *e){
	//第一种订时器的方式,利用timerEvent事件
	static long num = 0;
	static long num2 = 0;
	if (e->timerId() == id1){
		ui.labTimer->setText(QString::number(num++));
	}
	else if (e->timerId() == id2){
		ui.labTimer2->setText(QString::number(num2++));
	}
}

//重写eventFilter事件
bool QtForOpencv::eventFilter(QObject * obj, QEvent * ev){
	if (obj == ui.label)
	{
		if (ev->type() == QEvent::MouseButtonPress){
			QMouseEvent * e = static_cast<QMouseEvent *>(ev);
			QString str = QString("EventFilter: 鼠标按下 x=%1 y=%2").arg(e->x()).arg(e->y());
			qDebug() << str;
			//只有鼠标扫下事件自己处理
			return true;
		}
	}
	//其它事件交给父类处理
	return QWidget::eventFilter(obj,ev);
}


运行结果见下图. 

第一个lable用于重写一些鼠标有关的事件, 可以在vs的信息栏看到这个事件输出信息.

其它几个lable 演示了定时器的用法.

image.png


代码说明:


(1)  订时器的实现方式有两种,一是利用timerEventg事件,另一种跟C#类似,使用一个QTimer类来实现.

(2)  event事件主要是负责事件的分发,有点像win32里面的消息循环中的case处理

      eventFilter是事件过滤器, 负责处理顶层消息拦截, 这个有点像是win32里面的消息勾子.

     它的关系是这样的: 

          image.png


(3) 所有控件都有可以被重写的消息, 上面例子里, 重写了lable的如下图所示的一些方法.

image.png

在vs的环境下, 重写这些方法时, 参数无法自动补全,这个真是意料之外的事.

所以最好查看QT的帮助, 复制它的函数定义来得快些.


再接下来勇哥想研究一下文件读写与数据流, 这些在工控软件里面用于写入客户需要的生产数据, 是常用的东东. 


--------------------- 

作者:hackpig
来源:
www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864