Qt隱藏框架的窗口部件的移動事件處理

問題描述:

我們的自定義的Qt窗口,大多采用了隱藏框架、然後自定義窗口標題欄的方式,實現了窗口的定製。但是在測試、使用過程中,經常出現拖動非標題欄位置窗口也跟着移動、甚至跳動的現象。

解決方案:

重寫窗口部件的三個事件函數,mousePressEvent,mouseMoveEvent,mouseReleaseEvent。

在窗口類的內部定義一個記錄鼠標按下位置的QPoint m_mousePressPoint;默認值是一個y值大於窗口標題欄高度的點,可設置爲QPoint(0,100)。

在mousePressEvent事件中,判斷是否是左鍵按下,若是,則記錄鼠標按下的點,並獲取鼠標按下時所在位置的窗口部件,並對鼠標按下的點重新定位:若鼠標按下點所在的窗口部件是標題欄內部的窗口部件,則按下點保持不變,否則,將按下點置爲默認值。

在mouseMoveEvent事件中,通過按下點的位置與標題欄高度的對比,決定是否執行移動操作。若按下點的位置小於標題欄高度,則移動,否則不移動。(爲了避免由於標題欄的部件的邊界區域寬度較大時,造成拖動標題欄下邊緣無效的情況發生,要考慮標題欄窗口部件相對於其父窗口(this)的相對位置)

在mouseReleaseEvent事件中,將按下點恢復到默認值(因爲點擊combobox後,不觸發mousePressEvent,所以不會對按下點設置位置,而是保持上次的值,因此可能導致移動事件判斷出錯)。

參考代碼如下:

QPoint SubstationAlarmDlg::m_mousePressPoint;//定義記錄鼠標按下點。

void SubstationAlarmDlg::mousePressEvent(QMouseEvent* event)
{
	if(event->button()==Qt::LeftButton)//判斷是否是左鍵點擊
	{
		m_mousePressPoint = event->pos();
		QWidget *tempWidget = childAt(m_mousePressPoint);
		if (tempWidget == ui.label_5 ||tempWidget == ui.titlelabel ||tempWidget == ui.closeBtn
			||tempWidget == ui.label_2 ||tempWidget == ui.label_4 ||tempWidget == ui.label_6
			||tempWidget == ui.label ) //(不包含最大化、最小化、還原、關閉按鈕)
		{
			;//判斷按下點所處的部件是否爲標題欄內的窗口部件,若是,不作爲。
		}
		else
		{
			m_mousePressPoint = QPoint(0,100);//若不是,重置爲初始值。
		}
	}
}


void SubstationAlarmDlg::mouseMoveEvent(QMouseEvent *event)
{
	QPoint tempPoint = event->pos();//獲取事件發生位置
	QRect selfRect = ui.logoWidget->geometry();//獲取窗口圖標相對於父窗體的矩形
	int y = selfRect.y();//獲取矩形的高度
	int tempHight = ui.logoWidget->height() + y;//獲取標題欄最下線到父窗體最上線的距離(作爲判斷對比值)
	if (m_mousePressPoint.y() < tempHight)//對比,確定是否移動。
	{
		int tempX = tempPoint.x() - m_mousePressPoint.x();
		int tempY = tempPoint.y() - m_mousePressPoint.y();
		int nowX = this->x();
		int nowY = this->y();
		nowX += tempX;
		nowY += tempY;
		this->move(nowX, nowY);
	}
}


void SubstationAlarmDlg::mouseReleaseEvent(QMouseEvent *event)
{
	m_mousePressPoint = QPoint(0, 100);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章