zoukankan      html  css  js  c++  java
  • Qt:移动无边框窗体(使用Windows的SendMessage)

    移动无边框窗体的代码网上很多,其原理都是一样的,但是是有问题的,我这里只是对其修正一下

    网上的代码仅仅实现了两个事件

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. void EditDialog::mousePressEvent(QMouseEvent *event)  
    2. {  
    3.     if (event->button() == Qt::LeftButton) {  
    4.         m_DragPosition = event->globalPos() - this->pos();  
    5.         event->accept();  
    6.     }  
    7. }  
    8.   
    9. void EditDialog::mouseMoveEvent(QMouseEvent *event)  
    10. {  
    11.     if (event->buttons() && Qt::LeftButton) {  
    12.         move(event->globalPos() - m_DragPosition);  
    13.         event->accept();  
    14.     }  
    15. }  

    但是这样就会有一个问题,就是当鼠标在一个实现了mousePressEvent的类上点击时(比如QPushButton)会被该类优先处理此事件

    而不会将事件传递到窗体的mousePressEvent中。继续,当移动鼠标到这个按钮外时(假设点在了QPushButton上)会触发窗体的mouseMoveEvent

    从而导致计算坐标时发生错误,此时你就会看到窗体闪了一下,变动了位置,鼠标也没有停在前面按下的按钮之上。

    解决办法也很简单,就是再多声明一个bool变量来判断,并实现mouseReleaseEvent即可

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. void EditDialog::mousePressEvent(QMouseEvent *event)  
    2. {  
    3.     if (event->button() == Qt::LeftButton) {  
    4.         m_Drag = true;  
    5.         m_DragPosition = event->globalPos() - this->pos();  
    6.         event->accept();  
    7.     }  
    8. }  
    9.   
    10. void EditDialog::mouseMoveEvent(QMouseEvent *event)  
    11. {  
    12.     if (m_Drag && (event->buttons() && Qt::LeftButton)) {  
    13.         move(event->globalPos() - m_DragPosition);  
    14.         event->accept();  
    15.     }  
    16. }  
    17.   
    18. void EditDialog::mouseReleaseEvent(QMouseEvent *)  
    19. {  
    20.     m_Drag = false;  
    21. }  


    这样,就完成了无边框窗体的拖动。可是,这样做的效率并不高,因为鼠标每次move时都会触发事件,计算位置,移动窗口,重绘窗口……

    当窗体上有QWebView部件时,特别是网页中有图片,Flash时,你就会发现用上面的方案去移动窗体时会非常不流畅。

    如果不考虑跨平台,只针对Windows平台,那么我建议用Windows下的标准方法,模拟标题栏移动消息,既简单又高效

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. void MainWindow::mousePressEvent(QMouseEvent *event)  
    2. {  
    3.     if (ReleaseCapture())  
    4.         SendMessage(HWND(this->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);  
    5.     event->ignore();  
    6. }  

     这样,在拖动窗体时只会在松开鼠标时才将窗体移动过去,这样就避免了第一种方法的低效率问题

    http://blog.csdn.net/aqtata/article/details/8902889

  • 相关阅读:
    HDU 2444 The Accomodation of Students (判断是否是二分图,然后求最大匹配)
    HDU 1045 Fire Net (二分匹配)
    Leangoo如何颠覆传统项目管理软件?
    团队协作神器:Leangoo
    Leangoo-让工作更简单
    leangoo 轻量级项目协作和列表管理平台
    团队协作中的“贵族”leangoo
    使用leangoo实现多泳道任务看板
    项目管理工具到底应该为谁服务?
    《精益创业实战》读书笔记
  • 原文地址:https://www.cnblogs.com/findumars/p/6375631.html
Copyright © 2011-2022 走看看