在研究医学图像可视化的时候,鼠标响应这里一直都有问题。研究了几天VTK的取点,还是会和Qt冲突。所以现在试试Qt的方式取点,看看能不能实现我的功能。

查了很多资料,这篇博文里的实例有部分参考了祥知道-CSDN博客这位博主的博客[QT]获取鼠标坐标以及按键响应-CSDN博客。他的界面很清晰明了,所以我做ui界面就参考了他的结构。这篇博文主要介绍了如何利用鼠标按下事件、鼠标释放事件实现自己的功能需求以及如何获取鼠标移动的坐标变换。

1. 鼠标按下事件、鼠标释放事件

步骤一:新建一个Qt项目,按照下图绘制ui界面。

VS2022联合Qt5开发学习9(QT5.12.3鼠标按下、释放、移动事件以及Qt上取标注点)-LMLPHP

步骤二:首先加入头文件:

#include <QMouseEvent>

在.h和.cpp文件中加入鼠标按下、释放事件的相关函数:

在之前的博客VS2022联合Qt5开发学习6(ui嵌入另一个ui、主界面与子界面传递信号、为Qt控件添加背景图片)_vs2022使用qt新加一个.ui界面-CSDN博客里,我介绍了Qt按钮Style的设置,这里正好用上,用于区分鼠标按下和释放事件触发时显示按钮的变化。

	QString style_active = "border:2px solid black;background:green";
	QString style_release = "border:2px solid black;";
鼠标状态:

枚举鼠标的状态:

enum MouseState //鼠标状态
{
	L_C,//left click
	R_C,
	M_C,
	L_DC,//left double click
	R_DC,
	Wheel,//wheel move
	Release
};

 设置控件初始状态:

void mousePoint::setMouseUIdefault()
{
	QString style_release = "border:2px solid black;";

	ui.lab_mR_D->setStyleSheet(style_release);
	ui.lab_mR->setStyleSheet(style_release);
	ui.lab_mL_D->setStyleSheet(style_release);
	ui.lab_mL->setStyleSheet(style_release);
	ui.lab_mM->setStyleSheet(style_release);
	ui.lab_mM_up->setStyleSheet(style_release);
	ui.lab_mM_down->setStyleSheet(style_release);
}

鼠标按键变化引起ui界面控件发生变化: 

void mousePoint::setMouseState(MouseState ms, int wheelVal)
{
	QString style_active = "border:2px solid black;background:green";
	QString style_release = "border:2px solid black;";
	setMouseUIdefault();
	switch (ms)
	{
	case L_C:
		ui.lab_mL->setStyleSheet(style_active);
		break;
	case R_C:
		ui.lab_mR->setStyleSheet(style_active);
		break;
	case M_C:
		ui.lab_mM->setStyleSheet(style_active);
		break;
	case L_DC:
		ui.lab_mL_D->setStyleSheet(style_active);
		break;
	case R_DC:
		ui.lab_mR_D->setStyleSheet(style_active);
		break;
	case Wheel:
		ui.lab_mM_val->setText(QString("%1").arg(wheelVal));
		if (wheelVal > 0)
		{// 放大
			ui.lab_mM_up->setStyleSheet(style_active);
			ui.lab_mM_down->setStyleSheet(style_release);
		}
		else
		{// 缩小
			ui.lab_mM_up->setStyleSheet(style_release);
			ui.lab_mM_down->setStyleSheet(style_active);
		}
		break;

	case Release:
		//setMouseUIdefault();
		break;
	}
}
鼠标按下:
void mousePoint::mousePressEvent(QMouseEvent* event)
{//单击
	// 如果是鼠标左键按下
	if (event->button() == Qt::LeftButton) {
		//qDebug() << "left click";
		setMouseState(MouseState::L_C, 0);
	}
	// 如果是鼠标右键按下
	else if (event->button() == Qt::RightButton) {
		//qDebug() << "right click";
		setMouseState(MouseState::R_C, 0);
	}
	else if (event->button() == Qt::MidButton) {
		//qDebug() << "mid click";
		setMouseState(MouseState::M_C, 0);
	}

}
鼠标释放:
void mousePoint::mouseReleaseEvent(QMouseEvent* event)
{//释放
	setMouseState(MouseState::Release, 0);
}
鼠标双击:
void mousePoint::mouseDoubleClickEvent(QMouseEvent* event)
{//双击
	// 如果是鼠标左键按下
	if (event->button() == Qt::LeftButton) {
		//qDebug() << "left double click";
		setMouseState(MouseState::L_DC, 0);
	}
	else if (event->button() == Qt::RightButton) {
		//qDebug() << "right double click";
		setMouseState(MouseState::R_DC, 0);
	}
}
滚轮操作:
void mousePoint::wheelEvent(QWheelEvent* event)
{//滚轮
	int wheel_val = event->delta();
	setMouseState(MouseState::Wheel, wheel_val);
}
运行结果:

鼠标响应界面

2. 制作跟随鼠标移动的圆

这个项目就接着上面那个实例接着做吧。

步骤一:加上头文件

#include <QPaintEvent>
#include <QPainter>

步骤二: 在.h和.cpp文件中加入鼠标移动、绘制圆并实时更新的相关函数:

绘制函数:
void mousePoint::paintEvent(QPaintEvent* event)
{
	QPainter painter(this);


	painter.setRenderHint(QPainter::Antialiasing);//反走样

	QFont font;
	painter.save();//保存旧的painter
	font = painter.font();
	font.setPointSize(12);
	painter.setFont(font);
	painter.setBrush(QBrush(QColor(200, 200, 100)));

	painter.drawEllipse(fastPoint, r, r);//原点为fastPoint,半径为30


	painter.restore();//回到旧的painter
}
鼠标移动:
void mousePoint::mouseMoveEvent(QMouseEvent* event)
{

	if (pushButton)
	{
		fastPoint = event->pos();
		update();//画出更新位置
	}
}
鼠标按下和释放:
void mousePoint::mousePressEvent(QMouseEvent* event)
{//单击
	// 如果是鼠标左键按下
	if (event->button() == Qt::LeftButton) {
		//qDebug() << "left click";
		setMouseState(MouseState::L_C, 0);
	}
	// 如果是鼠标右键按下
	else if (event->button() == Qt::RightButton) {
		//qDebug() << "right click";
		setMouseState(MouseState::R_C, 0);
	}
	else if (event->button() == Qt::MidButton) {
		//qDebug() << "mid click";
		setMouseState(MouseState::M_C, 0);
	}

	QPoint p = event->pos();
	if (event->button() == Qt::LeftButton && p.x() > fastPoint.x() - r / 2 &&
		p.x() < fastPoint.x() + r / 2 && p.y() > fastPoint.y() - r / 2
		&& p.y() < fastPoint.y() + r / 2)
		pushButton = true;

}

void mousePoint::mouseReleaseEvent(QMouseEvent* event)
{//释放
	setMouseState(MouseState::Release, 0);
	if (event->button() == Qt::LeftButton)
		pushButton = false;
}
运行结果:

制作跟随鼠标移动的圆

3. 获取鼠标坐标

懒得开新项目了,还是接着写好了(感觉这个项目被我堆成了巨无霸hhh)。

步骤一:加入头文件

#include <QDebug>

步骤二:在.h和.cpp文件中修改鼠标移动的相关函数:

鼠标移动:
void mousePoint::mouseMoveEvent(QMouseEvent* event)
{

	if (pushButton)
	{
		fastPoint = event->pos();
		update();//画出更新位置
	}

	QPoint p_ab = event->globalPos();
	qDebug() << "\n" ;
	qDebug() << "Position of the Mouse:" << p_ab;
	QPoint p_re = event->pos();

	QString str;
	str = QString("%1 , %2").arg(p_ab.x()).arg(p_ab.y());
	qDebug() <<"Position in the MainWindow:"<< str;

	str = QString("%1 , %2").arg(p_re.x()).arg(p_re.y());
	qDebug() << "Position in the Display Window:" << str;
}
运行结果:

 VS2022联合Qt5开发学习9(QT5.12.3鼠标按下、释放、移动事件以及Qt上取标注点)-LMLPHP

 

4. 用Qt实现取点

最后回到我一开始的目的,Qt取点。

修改一下鼠标按下函数: 
void mousePoint::mousePressEvent(QMouseEvent* event)
{//单击
	// 如果是鼠标左键按下
	if (event->button() == Qt::LeftButton) {
		//qDebug() << "left click";
		setMouseState(MouseState::L_C, 0);
		fastPoint = event->pos();
		update();//画出更新位置
	}
	// 如果是鼠标右键按下
	else if (event->button() == Qt::RightButton) {
		//qDebug() << "right click";
		setMouseState(MouseState::R_C, 0);
	}
	else if (event->button() == Qt::MidButton) {
		//qDebug() << "mid click";
		setMouseState(MouseState::M_C, 0);
	}

	QPoint p = event->pos();
	if (event->button() == Qt::LeftButton && p.x() > fastPoint.x() - r / 2 &&
		p.x() < fastPoint.x() + r / 2 && p.y() > fastPoint.y() - r / 2
		&& p.y() < fastPoint.y() + r / 2)
		pushButton = true;

}

 

修改后,只要点击左键就会画一个圆。

运行结果:

点击鼠标左键画圆

 

我写的这么详细,应该不需要我再把完整.h和.cpp文件发出来了吧。总得一步步做一遍,对每个函数的功能用法才会更清楚嘛。最后,如果你觉得这篇文对你有帮助,请给博主点赞收藏评论三连hhh 

01-19 08:07