Qt:无标题栏无边框程序的拖动和改变大小
From: http://blog.csdn.net/kfbyj/article/details/9284923
最近做项目遇到的问题,总结下。
有时候我们觉得系统的标题栏和按钮太丑太呆板,想做自己的标题栏以及最大化、最小化、关闭,菜单按钮,我们就需要
- setWindowFlags(Qt::FramelessWindowHint);
但是这样过后,我们就不能拖动窗口改变位置,以及拖动边缘改变窗口大小了。
有两种方案处理这种情况:
1.自己对mouseMoveEvent,mousePressEvent,mouseReleaseEvent 等事件进行处理。
2.Qt可以处理windows的消息。大家重新实现bool winEvent(MSG *message, long *result);(在此又一次感觉Qt的NB)
我刚开始使用第一种方法去实现的。移动窗口很容易做,大家可以去看看这个大大写的,比网上其他版本问题少些。
http://blog.csdn.net/aqtata/article/details/8902889
在窗口边缘按下鼠标拖动改变窗口大小就比较麻烦了。
我是这样做的:
在mousePressEvent 按下设置m_bPressed为真。
在mouseMoveEvent中m_bPressed为真且event->x() 在窗口边缘 及处理算出鼠标移动的增量 然后不断resize窗口。
至于如何为边缘的断定,就自己设定一个 差值 假如 在窗口边缘 ±4个px 就算在在该边缘就处理该resize。
这样做缺点很多,1.拖快了不行,很容易超过该差值 , 2.窗口抖动的厉害,一直在resize,3.要处理太多情况
鉴于上诉缺点于是乎就到处问人百度google。有了第二种方法:
第二种方法很好用,效果和有标题边框程序一样~~~
Qt居然可以处理windows消息。。
这里我们要重新实现winEvent ( MSG * message, long * result )
该虚函数在QWidget和QWizard以及QSizeGrip以及他们的子类中都可以实现。
如果你想停止Qt处理消息就返回true,并且设置result到你想要保存的值返回给window处理。否者的话返回false。
这里我们主要想处理WM_NCHITTEST消息。
The WM_NCHITTEST message is sent to a window in order to determine what part of the window corresponds to a particular screen coordinate. This can happen, for example, when the cursor moves, when a mouse button is pressed or released, or in response to a call to a function such as WindowFromPoint. If the mouse is not captured, the message is sent to the window beneath the cursor. Otherwise, the message is sent to the window that has captured the mouse.
A window receives this message through its WindowProc function.
WM_NCHITTEST的消息响应函数会根据鼠标当前的坐标来判断鼠标命中了窗口的哪个部位,消息响应函数的返回值指出了部位,例如它可能会返回HTCAPTION,或者HTCLIENT等。(其返回值有很多,请查阅MSDN)。
知道这个就好了,我们还是要判断下鼠标的位置,然后通过该位置保存到result给window处理。
其实就是我们的程序没有边框不能发送这些消息,我们把它告诉windows,然后windows帮我们处理拖动,改变大小等效果。所以效果和有边框有标题程序效果一样的。
头文件申明:
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- MainWindow(QWidget *parent = 0);
- ~MainWindow();
- protected:
- bool winEvent(MSG *message, long *result);
- };
CPP实现
- bool MainWindow::winEvent(MSG *message, long *result)
- {
- switch(message->message)
- {
- case WM_NCHITTEST:
- int xPos = GET_X_LPARAM(message->lParam) - this->frameGeometry().x();
- int yPos = GET_Y_LPARAM(message->lParam) - this->frameGeometry().y();
- if(this->childAt(xPos,yPos) == 0)
- {
- *result = HTCAPTION;
- }else{
- return false;
- }
- if(xPos > 18 && xPos < 22)
- *result = HTLEFT;
- if(xPos > (this->width() - 22) && xPos < (this->width() - 18))
- *result = HTRIGHT;
- if(yPos > 18 && yPos < 22)
- *result = HTTOP;
- if(yPos > (this->height() - 22) && yPos < (this->height() - 18))
- *result = HTBOTTOM;
- if(xPos > 18 && xPos < 22 && yPos > 18 && yPos < 22)
- *result = HTTOPLEFT;
- if(xPos > (this->width() - 22) && xPos < (this->width() - 18) && yPos > 18 && yPos < 22)
- *result = HTTOPRIGHT;
- if(xPos > 18 && xPos < 22 && yPos > (this->height() - 22) && yPos < (this->height() - 18))
- *result = HTBOTTOMLEFT;
- if(xPos > (this->width() - 22) && xPos < (this->width() - 18) && yPos > (this->height() - 22) && yPos < (this->height() - 18))
- *result = HTBOTTOMRIGHT;
- return true;
- }
- return false;
- }
把各种边界情况保存到result给windows处理,我们就省去很多事情,我想windows肯定比我们自己实现的效果要好多了。
以上的18 以及 22 是我对程序的边缘进行判断的范围。
因为
我做了边框阴影。阴影边框设定为20px所以在
- xPos > 18 && xPos < 22 其实就是我们假定的边框了。
@import url(http://www.cppblog.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
http://www.cppblog.com/biao/archive/2013/07/11/201704.html
Qt:无标题栏无边框程序的拖动和改变大小的更多相关文章
- Qt 无标题无边框程序的拖动和改变大小
最近做项目遇到的问题,总结下. 有时候我们觉得系统的标题栏和按钮太丑太呆板,想做自己的标题栏以及最大化.最小化.关闭,菜单按钮,我们就需要 setWindowFlags(Qt::FramelessWi ...
- Qt无边框MainWindow如何拖动四周改变大小
原来还有winEvent(), x11Event() and macEvent() 这些东西...不过貌似还需要找更好的办法,否则就无法跨平台了. 你需要重新处理部分窗体事件,以下代码适用于Windo ...
- 【转】C# 控件的自定义拖动、改变大小方法
在用VS的窗体设计器时,我们可以发现控件都是可以拖动的,并且还可以调整大小.怎么在自己的程序中可以使用上述功能呢? 下面的方法值得借鉴! using System; using System.Wind ...
- Delphi 实现窗体无标题栏有边框
1.在窗体的public区写下这一句: Procedure CreateParams(var Params :TCreateParams);override;2然后把光标停在这一行上,按下Ctrl+S ...
- 如何实现一个无边框Form的移动和改变大小(二)
接着上文:这里写链接内容 我们来说说一个比较复杂的实现, 效果如图: 注意为了能够凸显没有NC(NotClient)区域,我们额外用了3个panel分别放在窗体的左右和下部.用来模拟客户自己的控件. ...
- 如何实现一个无边框Form的移动和改变大小(一)
很多时候我们不希望使用Windows提供的窗体. 我们希望使用一个无边框的窗体,什么border,caption透明就行了. 下面我们来说下一些实现方法. 这个方法要求窗体自定义的border siz ...
- WINFROM 无边框窗体的移动和改变大小
因为去掉了边框 移动和调整大小都用不了了,可以调用WIN32的API来实现 1.定义必须常量 ; ; ; ; ; ; const int Guying_HTBOTTOMLEFT = 0x10; ; ...
- C# 控件的自定义拖动、改变大小方法
在用VS的窗体设计器时,我们可以发现控件都是可以拖动的,并且还可以调整大小.怎么在自己的程序中可以使用上述功能呢? 下面的方法值得借鉴! using System; using System.Wind ...
- Qt 无边框窗体改变大小 完美实现(全部自己实现)
近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...
随机推荐
- 关于ajax解析
出处:http://www.cnblogs.com/huashanlin/archive/2006/10/09/524707.html 要很好地领会Ajax技术的关键是了解超文本传输协议(HTTP), ...
- Linux小白最佳实践:《超容易的Linux系统管理入门书》(连载五)Linux系统的对话方式
本篇是Linux小白最佳实践第5篇,目的就是让白菜们了解Linux进程之间是如何对话的.之前连载的几篇,在微信上引起了很多的反响,有人也反映图多文字少,感觉没有干货.本篇选了大部分是实战讲解的&quo ...
- SEO前端优化
精减代码 清除网页中一些冗余的代码,网上有这样的工具,可以辅助完成,如果需要的话,我们可以把代码中的注释去掉,甚至空行之类的也去掉,尽量的减少代码量,从而减小页面体积. CSS Sprites 通俗点 ...
- 考虑virtual函数以外的其它选择
详情见<Effective C++>item35 1.使用non-virtual interface(NVI)手法,这是Template Method设计模式的一种特殊形式. 它以publ ...
- 关键字 virtual
Virtual是C++ OO机制中很重要的一个关键字.只要是学过C++的人都知道在类Base中加了Virtual关键字的函数就是虚拟函数(例如函数print),于是在Base的派生类Derived中就 ...
- Qt实现桌面动态背景雪花飘落程序
曾经收到过一份礼物,一个雪花飘落的程序,觉得效果很炫,通过前几篇的学习,我们已经掌握了贴图的一些技巧了,那么现在就可以自己实现了(当然你必须先拥有qt信号与槽的基础知识),这里先看效果 ...
- ubuntu10.4 server 配置VPN 安装pptp无法连接外网解决(转)
链接:http://www.ppkj.net/2011/04/30/ubuntu10-4-server-%E5%AE%89%E8%A3%85pptp%E6%97%A0%E6%B3%95%E8%BF%9 ...
- 《C++ Qt 设计模式》8|15拼图 小游戏的简单实现。拜托,别乱点!
第零章:介绍 看到这个游戏了,感觉蛮好玩的,实现了一下. 界面如下: 游戏玩法:在3×*3的矩阵中,每个按钮都可以点击,如果按钮四周有一个是空白,则点击此按钮则会移动到这个空白.按钮字母顺序变成“AB ...
- 一个功能齐全的IOS音乐播放器应用源码
该源码是在ios教程网拿过来的,一个不错的IOS音乐播放器应用源码,这个是我当时进公司时 我用了一晚上写的 图片都是在别的地方扒的,主要是歌词同步,及上一曲,下一曲,功能齐全了 ,大家可以学习一下吧 ...
- linux ubuntu 思源黑体安装
下载地址: 全部:700多M https://github.com/adobe-fonts/source-han-sans/releases/tag/1.001R 可选部分Github : http ...