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

 virtual bool nativeEvent(const QByteArray &, void *, long *) Q_DECL_OVERRIDE;

 {

     Q_UNUSED(eventType);

     MSG* msg = reinterpret_cast(message);

     if (winEvent(msg, result))

     {

         return true;

     }

     else

     {

         return QWidget::nativeEvent(eventType, message, result);

     }

 }

 如下方法是在qt事件循环之前调用的,如果返回值为true,则该事件循环不进入qt事件循环,否则进入,result是一个输出型参数,我们可以通过赋值给result不同的值,来控制鼠标的状态

 HTCAPTION:鼠标可以拖拽

 HTLEFT / HTRIGHT:鼠标可以左右拖拽

 HTTOP / HTBOTTOM:鼠标可以上下拖拽

 HTTOPLEFT / HTBOTTOMRIGHT:鼠标可以左上或者右下拖拽

 HTTOPRIGHT / HTBOTTOMLEFT:鼠标可以右上或者左下拖拽

 bool CCailianMainWindow::winEvent(MSG *message, long *result)

 {

     static int width = ;//可检测到鼠标状态的宽度

     bool res = false;

     if (isMaximized())

     {

         return res;

     }

     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 (QWidget * childW = this->childAt(xPos, yPos))

         {

             if (childW == m_WindowTitle)//我自己的窗口头,支持鼠标拖拽

             {

                 *result = HTCAPTION;

                 res = true;

             }

         }

         else

         {

             return res;

         }

         if (xPos >=  && xPos < width)

         {

             *result = HTLEFT;

             res = true;

         }

         if (xPos > (this->width() - width) && xPos < this->width())

         {

             *result = HTRIGHT;

             res = true;

         }

         if (yPos >=  && yPos < width)

         {

             *result = HTTOP;

             res = true;

         }

         if (yPos > (this->height() - width) && yPos < this->height())

         {

             *result = HTBOTTOM;

             res = true;

         }

         if (xPos >=  && xPos < width && yPos >=  && yPos < width)

         {

             *result = HTTOPLEFT;

             res = true;

         }

         if (xPos > (this->width() - width) && xPos < this->width() && yPos >=  && yPos < width)

         {

             *result = HTTOPRIGHT;

             res = true;

         }

         if (xPos >=  && xPos < width && yPos >(this->height() - width) && yPos < this->height())

         {

             *result = HTBOTTOMLEFT;

             res = true;

         }

         if (xPos > (this->width() - width) && xPos < this->width() && yPos >(this->height() - width) && yPos < this->height())

         {

             *result = HTBOTTOMRIGHT;

             res = true;

         }

     }

     return res;

 }
图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实例

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

  1. qt 拖拽 修改大小(二)

    最近项目需要实现windows下橡皮筋的效果,所以对此做了一些了解,特此记录. 首先windows系统是支持橡皮筋效果的,需要使用win32方 法:SystemParametersInfo(SPI_S ...

  2. qt 拖拽 修改大小(使用了nativeEvent和winEvent)

    http://www.cnblogs.com/swarmbees/p/5621543.html http://blog.sina.com.cn/s/blog_9e59cf590102w3r6.html

  3. Qt::QWidget 无默认标题栏边框的拖拽修改大小方式

    开发环境:win10+vs2015+qt5.9.1 背景:开发过程中,一般很少会使用系统提供的标题栏和边框:往往都是自定义一个自己设计的方案.这时候在QWidget中需要加上flag:Qt::Fram ...

  4. Qt拖拽界面 (*.ui) 缩放问题及解决办法

    问题 使用Qt Designer 设计的界面,在缩放的时候不能随着主窗口一起缩放. 解决办法 之前遇到这个问题的时候,都是直接重写resizeEvent接口来实现的,在自动生成的Ui_Widget或U ...

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

    经常遇到这样的情况,在我们使用Delphi的可视化工具进行UI设计的时候,我们拖拽TEdit或者Label组件,并且在可视化界面上设置它们的长.宽 但是当我们编译和运行程序的时候,却发现真正显示出来的 ...

  6. Qt拖拽界面 (*.ui) 缩放问题及解决办法(在最顶层放一个Layout)

    问题 使用Qt Designer 设计的界面,在缩放的时候不能随着主窗口一起缩放. 解决办法 之前遇到这个问题的时候,都是直接重写resizeEvent接口来实现的,在自动生成的Ui_Widget或U ...

  7. react之每日一更(实现canvas拖拽,增、删、改拖拽模块大小功能)

    效果图: import React, { Component } from 'react'; import scaleImage from './images/scale.png'; import c ...

  8. jQuery拖拽改变元素大小

    一个非常简单的例子,体验效果:http://keleyi.com/keleyi/phtml/jqtexiao/29.htm 以下是完整代码,保存到HTML文件打开也可以体验效果. <!DOCTY ...

  9. 超强的纯 CSS 鼠标点击拖拽效果

    背景 鼠标拖拽元素移动,算是一个稍微有点点复杂的交互. 而在本文,我们就将打破常规,向大家介绍一种超强的仅仅使用纯 CSS 就能够实现的鼠标点击拖拽效果. 在之前的这篇文章中 -- 不可思议的纯 CS ...

随机推荐

  1. pytest简介

    pytest有哪些优点? 允许直接使用assert进行断言,而不需要使用self.assert*; 可以自动寻找单测文件.类和函数; Modular fixtures可以用于管理小型或参数化的测试信息 ...

  2. Linux的vim编辑器

    vim编辑器常用的三种模式 vim /文件路径 进入编辑器,编辑该文件 例:vim /etc/passwd 命令行模式:在编辑器中直接输入命令 dd:删除光标所在的一行 ndd:删除光标所在的向下的n ...

  3. 动态规划——Dungeon Game

    这又是个题干很搞笑的题目:恶魔把公主囚禁在魔宫的右下角,骑士从魔宫的左上角开始穿越整个魔宫到右下角拯救公主,为了以最快速度拯救公主,骑士每次只能向下或者向右移动一个房间, 每个房间内都有一个整数值,负 ...

  4. sudo命令详解

    语法 sudo(选项)(参数) 选项 选项 说明 -b 在后台执行指令: -h 显示帮助: -H 将HOME环境变量设为新身份的HOME环境变量: -k 结束密码的有效期限,也就是下次再执行sudo时 ...

  5. (lua) 基于cocos 的插入光效

    具体的表现是:移动滚动容器到头部, 新增icon淡入并掉入格子,显示格子中的图标,icon放大并淡出 function UISkyResource:playActivedEffect(id) then ...

  6. 百度语音合成AI

    注意:不要使用Dw编辑PHP代码,会因为编码问题出错!!<?php require_once 'AipSpeech.php'; // 你的 APPID AK SK const APP_ID = ...

  7. 源码安装python +NGINX 的坎坷路 +uwsgi安装 部署django 的CRM项目

    一.Nginx安装(基于ubuntu17.10 版本) 首先我们是基于源码安装,主要有如下步骤 1.安装依赖包 1.安装gcc g++的依赖库 sudo apt-get install build-e ...

  8. linux-Vim命令合集

    Vim命令合集 命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filena ...

  9. Python-JSON和pickle

    笔记:一:简介 (1)JSON (JavaScript Object Notation) 是一种轻量级(XML重量级)的数据交换格式. 是为了数据交换而定制的一种规则,它基于ECMAScript的一个 ...

  10. PHP 5.x和PHP 7 Closure不同行为问题

    同样一段闭包代码,PHP 7 ok的,PHP 5.5.11(Windows 开发机器)上却报错,以为是PHP 5 bug,原来是用法不对,记录一下~ 原代码(自己写的框架的路由部分)最初是这样写的: ...