【Qt】 【功能】Qt 鼠标事件实现窗口拖动功能

本文详细介绍了在Qt中实现自定义窗口拖动的两种方法。第一种方法通过全局坐标跟踪鼠标移动,第二种方法使用相对坐标进行计算。文章解释了为何相对坐标法无需更新起始坐标,以及如何正确实现窗口的平滑移动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

功能: 鼠标按住窗口的自定义标题栏后,移动拖动整个窗口功能

实现方式:

方法一:其中CVideoPlayerApp是自定义标题栏的QWidget。

void CVideoPlayerApp::mousePressEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton)
	{
		if (event->y() < VALUE_DIS || event->x() < VALUE_DIS || rect().width() - event->x() < VALUE_DIS)
		{
			event->ignore();
			return;
		}
		m_ptPress = event->globalPos();
		m_bLeftButtonPress = true;
	}
	event->ignore();
}

void CVideoPlayerApp::mouseMoveEvent(QMouseEvent *event)
{
	
	if (m_bLeftButtonPress)
	{
		m_ptMove = event->globalPos();
		int x = (m_ptMove - m_ptPress).x();
		int y = (m_ptMove - m_ptPress).y();
		emit sigMouseMoveEvent(x, y);  //触发对应的槽函数,移动窗口
		m_ptPress = m_ptMove;
	}
	event->ignore();
}

void CVideoPlayerApp::mouseReleaseEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton)
	{
		m_bLeftButtonPress = false;
	}
	event->ignore();
}
void CVideoPlayerApp::slotMouseMoveEvent( int x, int y )
{
	move(this->pos().x() + x, this->pos().y() + y);

	// 更新窗口位置
	updateWindowsPos();
}

方法二:其中MarkBuildDrawWgt就是一个含有自定义标题栏的QWidget。

void MarkBuildDrawWgt::mousePressEvent(QMouseEvent *event)
{
	if (event->button()==Qt::LeftButton && ui.frameMarkBuildDarwTitle->underMouse())
	{
		m_bPress = true ;
		m_lastPoint = event->pos(); //相对坐标
	}
	QWidget::mousePressEvent(event);
}
void MarkBuildDrawWgt::mouseMoveEvent(QMouseEvent *event)
{
	if (m_bPress)
	{
		this->move(pos()+(event->pos()-m_lastPoint));
	}
	QWidget::mouseMoveEvent(event);
}
void MarkBuildDrawWgt::mouseReleaseEvent(QMouseEvent *event)
{
	
	m_bPress = false ;
	QWidget::mouseReleaseEvent(event);
	
}

 方法二思路:  鼠标按下事件中监听是否为鼠标左键,并且是否在自定义标题内 -->  记录下按下的相对坐标位置,并记录按下的状态(bool)。

        鼠标移动事件中监听是否正处于按下状态  --》 计算当前鼠标相对位置 -  按下的相对坐标位置  --》 移动窗口相应的距离  --》更新按下的相对坐标位置。

【问题】方法二中为什么相对坐标可以,感觉都是窗口move结束和开始的差值。为什么方法一中,需要不断更新上一个点的坐标?而方法二却不用?

  假设,鼠标按下的点是子窗口的左上角的点,也就是(0,0)。那么但鼠标向左在移动10px后,其鼠标相对子窗口而言是(-10,0)。然后子窗口向左移动10px后,这个过程中,鼠标移动只有这一次执行move() ,而不是1px1px的执行。

然后当再次执行时候,鼠标向下移动10px的时候,其还是(0,10)而不是(-10,10)。这里就是关键,第二次执行event->pos()的时候,其减去的那个按下的点相对坐标没边,但其绝对坐标其实已经改变了,这就是为什么相对坐标可以直接相减,而不用在对按下点重新赋值。而用绝对路径的方法时,如果还用按下的点的绝对坐标为准,那么第二次计算的时候,如果把第一次窗口移动会原来的位置就每错了。

另一个关键点: 无法方法一还是二的,其MouseMoveEvent()其不要看成连续的,看出是间段的理解就好了

其实可以用向量的方法来理解。

【问题】这个与Mouse Tracking有关系吗?我没有设置这个也可以正常运行。

如果想触发mouseMoveEvent()这个鼠标移动的响应函数,则必须要设置窗体(或控件)是可以Mouse Tracking的,不然程序不会进入mouseMoveEvent()函数。

[QT]获取鼠标坐标以及按键响应

 

【注意】从实现效果上来看,用复杂的子窗口,他在移动的时候,会出现拖尾重影的效果,无论是用相对还是全局坐标

 

 

 

 

 

qt开发之获取鼠标的相对位置和绝对位置

相对坐标: 相对于当前MousePressEvent的窗口而已,即子窗口。

绝对坐标: 相对于桌面而已的坐标。

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值