移動無邊框窗體的代碼網上很多,其原理都是一樣的,但是是有問題的,我這里只是對其修正一下
網上的代碼僅僅實現了兩個事件
- void EditDialog::mousePressEvent(QMouseEvent *event)
- {
- if (event->button() == Qt::LeftButton) {
- m_DragPosition = event->globalPos() - this->pos();
- event->accept();
- }
- }
- void EditDialog::mouseMoveEvent(QMouseEvent *event)
- {
- if (event->buttons() && Qt::LeftButton) {
- move(event->globalPos() - m_DragPosition);
- event->accept();
- }
- }
但是這樣就會有一個問題,就是當鼠標在一個實現了mousePressEvent的類上點擊時(比如QPushButton)會被該類優先處理此事件
而不會將事件傳遞到窗體的mousePressEvent中。繼續,當移動鼠標到這個按鈕外時(假設點在了QPushButton上)會觸發窗體的mouseMoveEvent
從而導致計算坐標時發生錯誤,此時你就會看到窗體閃了一下,變動了位置,鼠標也沒有停在前面按下的按鈕之上。
解決辦法也很簡單,就是再多聲明一個bool變量來判斷,並實現mouseReleaseEvent即可
- void EditDialog::mousePressEvent(QMouseEvent *event)
- {
- if (event->button() == Qt::LeftButton) {
- m_Drag = true;
- m_DragPosition = event->globalPos() - this->pos();
- event->accept();
- }
- }
- void EditDialog::mouseMoveEvent(QMouseEvent *event)
- {
- if (m_Drag && (event->buttons() && Qt::LeftButton)) {
- move(event->globalPos() - m_DragPosition);
- event->accept();
- }
- }
- void EditDialog::mouseReleaseEvent(QMouseEvent *)
- {
- m_Drag = false;
- }
這樣,就完成了無邊框窗體的拖動。可是,這樣做的效率並不高,因為鼠標每次move時都會觸發事件,計算位置,移動窗口,重繪窗口……
當窗體上有QWebView部件時,特別是網頁中有圖片,Flash時,你就會發現用上面的方案去移動窗體時會非常不流暢。
如果不考慮跨平台,只針對Windows平台,那么我建議用Windows下的標准方法,模擬標題欄移動消息,既簡單又高效
- void MainWindow::mousePressEvent(QMouseEvent *event)
- {
- if (ReleaseCapture())
- SendMessage(HWND(this->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
- event->ignore();
- }
這樣,在拖動窗體時只會在松開鼠標時才將窗體移動過去,這樣就避免了第一種方法的低效率問題
http://blog.csdn.net/aqtata/article/details/8902889