qt 拖拽 修改大小

写次篇文章之前,qt窗口的放大缩小和拖拽我都是通过setGeometry方法实现的,但是作为windows程序,windows支持橡 皮筋式(拖拽时有一个虚框)拖拽和拉伸。通过setGeometry方式实现功能是没有这种效果,幸好qt5中提供了一个本地事件处理接口 nativeEvent,具体功能可以看帮助文档,本文只讲述用该接口实现窗口放大、缩小和拖拽,具体实现代码如下:

  1 virtual bool nativeEvent(const QByteArray &, void *, long *) Q_DECL_OVERRIDE;
  2
  3 {
  4
  5     Q_UNUSED(eventType);
  6
  7     MSG* msg = reinterpret_cast(message);
  8
  9     if (winEvent(msg, result))
 10
 11     {
 12
 13         return true;
 14
 15     }
 16
 17     else
 18
 19     {
 20
 21         return QWidget::nativeEvent(eventType, message, result);
 22
 23     }
 24
 25 }
 26
 27 如下方法是在qt事件循环之前调用的,如果返回值为true,则该事件循环不进入qt事件循环,否则进入,result是一个输出型参数,我们可以通过赋值给result不同的值,来控制鼠标的状态
 28
 29 HTCAPTION:鼠标可以拖拽
 30
 31 HTLEFT / HTRIGHT:鼠标可以左右拖拽
 32
 33 HTTOP / HTBOTTOM:鼠标可以上下拖拽
 34
 35 HTTOPLEFT / HTBOTTOMRIGHT:鼠标可以左上或者右下拖拽
 36
 37 HTTOPRIGHT / HTBOTTOMLEFT:鼠标可以右上或者左下拖拽
 38
 39 bool CCailianMainWindow::winEvent(MSG *message, long *result)
 40
 41 {
 42
 43     static int width = 4;//可检测到鼠标状态的宽度
 44
 45     bool res = false;
 46
 47     if (isMaximized())
 48
 49     {
 50
 51         return res;
 52
 53     }
 54
 55     switch (message->message)
 56
 57     {
 58
 59     case WM_NCHITTEST:
 60
 61         int xPos = GET_X_LPARAM(message->lParam) - this->frameGeometry().x();
 62
 63         int yPos = GET_Y_LPARAM(message->lParam) - this->frameGeometry().y();
 64
 65         if (QWidget * childW = this->childAt(xPos, yPos))
 66
 67         {
 68
 69             if (childW == m_WindowTitle)//我自己的窗口头,支持鼠标拖拽
 70
 71             {
 72
 73                 *result = HTCAPTION;
 74
 75                 res = true;
 76
 77             }
 78
 79         }
 80
 81         else
 82
 83         {
 84
 85             return res;
 86
 87         }
 88
 89         if (xPos >= 0 && xPos < width)
 90
 91         {
 92
 93             *result = HTLEFT;
 94
 95             res = true;
 96
 97         }
 98
 99         if (xPos > (this->width() - width) && xPos < this->width())
100
101         {
102
103             *result = HTRIGHT;
104
105             res = true;
106
107         }
108
109         if (yPos >= 0 && yPos < width)
110
111         {
112
113             *result = HTTOP;
114
115             res = true;
116
117         }
118
119         if (yPos > (this->height() - width) && yPos < this->height())
120
121         {
122
123             *result = HTBOTTOM;
124
125             res = true;
126
127         }
128
129         if (xPos >= 0 && xPos < width && yPos >= 0 && yPos < width)
130
131         {
132
133             *result = HTTOPLEFT;
134
135             res = true;
136
137         }
138
139         if (xPos > (this->width() - width) && xPos < this->width() && yPos >= 0 && yPos < width)
140
141         {
142
143             *result = HTTOPRIGHT;
144
145             res = true;
146
147         }
148
149         if (xPos >= 0 && xPos < width && yPos >(this->height() - width) && yPos < this->height())
150
151         {
152
153             *result = HTBOTTOMLEFT;
154
155             res = true;
156
157         }
158
159         if (xPos > (this->width() - width) && xPos < this->width() && yPos >(this->height() - width) && yPos < this->height())
160
161         {
162
163             *result = HTBOTTOMRIGHT;
164
165             res = true;
166
167         }
168
169     }
170
171     return res;
172
173 }

图1 拖拽

图2 修改大小

如上图所示,红色箭头指的就是拖拽和改变大小时出现的白色框

?

这样处理后的标题栏(m_WindowTitle)不能接受到mouseDoubleClickEvent事件,因此还需要自己手动修改窗口大小,代码如下,添加到上述swtich语句中

case WM_NCLBUTTONDBLCLK:

{

HWND hWnd = (HWND)this->winId();

if (::IsZoomed(hWnd))

{

ShowWindow(hWnd, SW_RESTORE);

}

else

{

ShowWindow(hWnd, SW_MAXIMIZE);

}

res = false;

}

break;

注意:要支持windows的这种特性,需要通过代码设置

showFullWindow:true代表拖动和改变大小时窗口实时变化;false代表橡皮筋式放大,如上图所示

SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, showFullWindow ? TRUE : FALSE, NULL, 0);

================================================

时隔10几天,当我测试新功能时发现一个问题,特此记录:

在xp系统上qt程序没有任务栏菜单,但是win7和win10正常,给qt程序手动添加?Qt::WindowSystemMenuHint属性后,3系统都有菜单,但是nativeEvent方法不能放大缩小了,解决办法暂时没找到

====================================

今儿突然想到QMainWindow,这个右下角有一个可以支持放大做小的功能,最后看了源码,发现由一个QSizeGrip类,这个类可以实现所在顶层 QWindow的放大和缩小,特此记录?,此时结果如下图3。这个类支持橡皮筋放大缩小,和前文所述nativeEvent实现效果相同

图3
QSizeGrip实例

时间: 2024-12-05 03:03:53

qt 拖拽 修改大小的相关文章

qt 拖拽 修改大小(二)

最近项目需要实现windows下橡皮筋的效果,所以对此做了一些了解,特此记录. 首先windows系统是支持橡皮筋效果的,需要使用win32方 法:SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, showFullWindow, NULL, 0);showFullWindow是一个变量,如果需要windows默认支持橡皮筋则需要传递参数false,否则传递参数true,如果使用 windows默认的橡皮筋缩放,效果如图1所示,会产生一个矩形框,不管是窗口移

解决Delphi图形化界面的TEdit、TLable等组件手动拖拽固定大小,但是编译之后显示有误的情况

经常遇到这样的情况,在我们使用Delphi的可视化工具进行UI设计的时候,我们拖拽TEdit或者Label组件,并且在可视化界面上设置它们的长.宽 但是当我们编译和运行程序的时候,却发现真正显示出来的 TEdit或者TLabel组件并不是我们在可视化界面所拖拽的长和宽(显示的“有问题”) 这个时候我们可以参考下面的具体事例解决: 当然这只是其中的一种方法,绝对还有其他的方法,而且我也不知道下面所讲的这种方法是不是很好的,所以还待补充 1.我们在Delphi的可视化界面上需要一个TEdit和TLa

jquery 实现div边界拖拽控制大小

html <div id="container"> <!-- Left side --> <div id="left"> This is the left side's content! </div> <!-- Right side --> <div id="right"> <!-- Actual resize handle --> <div id=&quo

atitit.D&amp;D drag&amp;drop拖拽文件到界面功能 html5 web 跟个java swing c#.net c++ 的总结

atitit.D&D drag&drop拖拽文件到界面功能 html5 web 跟个java swing c#.net c++ 的总结 1. DND的操作流程 1 2. Html5 注解事件 document.dragover >>preventDefault 1 3. 代码(js) 1 4. C++ 实现拖曳 2 5. QT拖拽功能简介 - pcsuite的专栏 - 博客频道 - CSDN.NET.htm 2 1. DND的操作流程 Dragenter 事件::更改提示的颜色

JQuery拖拽改变元素的尺寸

"元素拖拽改变大小"其实和"元素拖拽"一个原理,只是所动态改变的对象不同而已,主要在于 top.left.width.height 的运用,相对实现起来也非常容易.以下附出源码原型,弄明白了原理再扩展其他实际应用,思路就变得简单.清晰得多了.先来看看效果:塔河县臧清机械 下面是 JavaScript Code view source print? 01 <script type="text/javascript"> 02     /*

独创轻松实现拖拽,改变层布局

通过JS实现拖拽变更层布局的代码,改变当前行的第一列,同时改变其他行的布局 <!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>

H5拖拽事件-- 自定义创建a标签热区

有两个BUG未更正, 1.拖拽后,动态创建的div始终在鼠标的下方,导致拖拽定位不准确 2.当窗口为自适应时,定位left为百分比,窗口改变大小时会存在定位偏差 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="./jquery-1

threejs 限制物件只能在指定平面上拖拽

threejs提供有 DragController.js的例子来辅助拖拽 该例子可以在基于当前屏幕的x和y轴上拖拽物体,但是它不能影响z轴. 查看代码,可以在touchStart\mousedown下找到下述代码: _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld

Qt无边框窗体-最大化时支持拖拽还原

目录 一.概述 二.效果展示 三.demo制作 1.设计窗体 2.双击放大 四.拖拽 五.相关文章 原文链接:Markdown模板 一.概述 用Qt进行开发界面时,既想要实现友好的用户交互又想界面漂亮,那么自定义界面就必不可少.其中有一个操作就是是我们每一个Qter开发者都要会的,而且是经常进行的. Qt::FramelessWindowHint这个属性想必大家都使用过,有些同学可能对这个属性很了解,也用的是炉火纯青,今天我们也来说说这个属性. 关于这个无边框属性网上也有一些文章,有些谈论的是b