【QT】 事件

介绍QT Event以及Event Filter事件处理的内容
1.手动发送事件流程:
(1)构造自己的事件对象:

				QEvent *evt = new QEvent(QEvent::Close);

(2)发送给指定的对象

				QApplication::sendEvent(this,evt);

2.定制某个控件的事件处理:
(1)确定需要对哪些控件的哪些事件,通常的close以及Key和keyboard事件;
(2)重写该对象的event()函数;
3.事件过滤流程:
(1)确定自己需要过滤处理哪些对象的那些事件;
(2)构造自己的事件过滤类:重写该类的eventFilter函数;
(3)在主程序中实例化一个过滤类对象;
(4)调用该过滤类对象的installEventFilter(receiver,QEvent *event)

QT中鼠标事件:
继承于QWidget

void mouseDoubleClickEvent(QMouseEvent* event)
void mouseMoveEvent(QMouseEvent *event)
void mousePressEvent(QMouseEvent* event)
void mouseReleaseEvent(QMouseEvent* event)

重写这四个函数就能够自定义控件支持鼠标操作。
QT中用QMouseEvent类来表达一个鼠标事件
x,y:坐标
globalX,globalY:全局坐标(相对于整个屏幕)
button:鼠标左键、右键、中键

QT 中 bool mouseTracking:
这个属性保存的是窗口部件跟踪鼠标是否生效。
如果鼠标跟踪失效(默认),当鼠标被移动的时候只有在至少一个鼠标按键被按下时,这个窗口部件才会接受鼠标移动时间;
如果鼠标跟踪生效,如果没有按键被按下,这个窗口部件也会接受鼠标移动事件。

	ui.label->setMouseTracking(true);

QT中void QObject::installEventFilter(const QObject *obj):
安装事件过滤器obj到这个对象;
事件过滤器就是接收所有被发送到这个对象的事件的对象。这个过滤器可以停止事件或者把它再转给这个对象;
事件过滤器obj通过它的eventFilter()函数来接收事件。如果事件被过滤了(比如,停止了),eventFilter()函数必须返回真,否则它必须返回假;
如果有多个事件过滤器被安装到同一个对象上,最后一个被安装的事件过滤器将先被激活。

class test_201901035 : public QMainWindow
{
	Q_OBJECT

public:
	test_201901035(QWidget *parent = 0);
	~test_201901035();
protected:
	bool eventFilter(QObject* obj, QEvent* evt);

private:
	Ui::test_201901035Class ui;
};
test_201901035::test_201901035(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	ui.label->setMouseTracking(true);
	//为label窗体安装一个过滤器
	ui.label->installEventFilter(this);
}
bool test_201901035::eventFilter(QObject* obj, QEvent* evt)
{
	if (qobject_cast<QLabel*>(obj) == ui.label)//或者obj == ui.lbImg
	{
		//QT QEvent转换未QMouseEvent等子类
		QMouseEvent *msEvent = static_cast<QMouseEvent*>(evt);
		//看鼠标有没有Move消息
		if (msEvent->type() == QEvent::MouseMove)
		{
			//globalPos()获取的鼠标位置是鼠标偏离电脑屏幕左上角(x=0,y=0)的位置
			QPoint pt = msEvent->globalPos();
			//将绝对位置对应到控件的相对位置
			pt = ui.label->mapFromGlobal(pt);
			//int变量转QString变量的一个方法是用QString::number函数来转换
			QString strXY = "move(x,y)=(" + QString::number(pt.x()) + "," + QString::number(pt.y()) + ")" + "event(x,y)=(" + QString::number(msEvent->pos().x()) + "," + QString::number(msEvent->pos().y()) + ")";
			ui.statusBar->showMessage(strXY);
			return true;
		}
		else if (msEvent->type() == QEvent::MouseButtonPress)
		{
			if (msEvent->buttons() == Qt::LeftButton)
			{
				//由pos()获取的位置是主窗口(widget窗口)左上角(边框的左上角,外左上角)相对于电脑屏幕的左上角(x=0,y=0)偏移位置
				QPoint pt = msEvent->pos();
				QSize lbSize = ui.label->size();
				QString strRate;
				int inBubble = 0;
				const QString strXY = "(" + QString::number(pt.x()) + "," + QString::number(pt.y()) + ")";
				// 窗口坐标转换图片坐标
				Point2f srcPt;
				srcPt = Point2f(pt.x()*srcSize.width()*1.0 / lbSize.width(), pt.y()*srcSize.height()*1.0 / lbSize.height());
				for (int i = 0; i < solderjointcontours.size(); i++)
				{
					if (pointPolygonTest(solderjointcontours[i], srcPt, false) == 1)
					{
						strRate = QString::number(contourArea(solderjointcontours[i]));
						inBubble = 1;
						break;
					}
				}
				
				if (inBubble == 0)
				{
					strRate = "";
				}
				QLabel* posLabel = new QLabel(this);
				posLabel->setStyleSheet("color:blue");
				posLabel->setGeometry(pt.x(), pt.y() + 10, 55, 10);
				posLabel->setText(strRate);
				posLabel->show();

				ui.statusBar->showMessage(strRate);
				return true;
			}
			else if (msEvent->buttons() == Qt::RightButton)
			{
				QList<QLabel*> lbs = this->findChildren<QLabel*>();
				foreach(QLabel* lbTmp, lbs)
				{
					if (lbTmp != ui.label)
						delete lbTmp;
				}
			}

		}
	}
	return QMainWindow::eventFilter(obj, evt);
}

猜你喜欢

转载自blog.csdn.net/weixin_42104289/article/details/86137651