简单点说,是在windows下实现窗口拖动和改变大小,一种方法是重载mousePressEvent系列全家福函数,然后在mouseMoveEvent中实现边移鼠标窗口就一边重绘。这种方法网上资料很多,见下:
https://www.cnblogs.com/findumars/p/5518590.html
这种方法缺点是移动的时候窗口闪烁厉害。摒弃。但该方法给了一个很好的思路。
另一种方法:
看到MFC中有调用NCHitTest方法的,这个方法是当鼠标触碰到非客户区时触发,然后调用windows api,实现窗口移动,参照下:
https://bbs.csdn.net/topics/350134227
在这篇帖子的最下方,有MFC改变窗口的方法。
于是我也想到了用Qt调windows api,反正我也不想做跨平台的软件,咳咳。然后发现了Qt有nativeEvent函数,捕获本地所有事件,重载之,专门处理鼠标移动信号。ok,实现了,但绝不完美!为何,继续看。
重载nativeEvent的方法网上查查,有第三个参数Long* result,result=HTLEFT时,鼠标就会变成横向双箭头图案,其他就参照MFC实现吧,后面会给出代码。
然后我们来看哪里不完美。Qt没有非客户区的概念,但类之间的信号传递很明显,当顶层窗口的最外层布局这样设置:
m_layoutMain->setMargin(0);
那么鼠标移到边缘时,鼠标信号的捕获是被最上层的子控件捕获了,实际上就触发不了顶层窗口的nativeEvent了。退而求其次,以为把边界设成5就可以了么?是的,不美观点,设成5确实就可以了,但如果想触发拖动事件的范围也是5,就会发现,鼠标在边界的5范围内,是横向双箭头图案,继续往里移,OK,进入子控件了,鼠标移动事件不触发了,鼠标一直是横向双箭头图案,何况,5也是接受不了的,我要0,不能忍,继续想办法。
然后就想到了过滤器,接着发现了Qt5.7的一个bug。过滤器,在顶层窗口实现nativeEventFilter方法,接着在qApp安装过滤器。
过滤器其实一点都不复杂,选个类A,在类A中实现nativeEventFilter方法后,建个对象a,只要在其他类用installNativeEventFilter(&a)方法安装过滤器,那个这个被安装过滤器的类,接收到了事件后,就会优先发给a来处理,而在qApp中安装过滤器,qApp是第一个接收到消息的,会全部先丢给a处理,a吃剩的残羹冷炙还给qApp,qApp再拿去分给其他改领盒饭的类。怎么算吃剩呢,在过滤器中return false就是吃剩不要了。然后上代码了
这是Class A中的方法,判断鼠标是否在规定