[Qt]不带标题栏(FramelessWindowHint)的窗体移动及调整大小

2023-11-01

Qt窗体若设置了

setWindowFlags (Qt::FramelessWindowHint);


运行后该窗体是无法进行移动和调整大小的,那要如何才能让它和普通窗体一样进行移动和调整其大小的呢?方案如下:

 
void QFramelessWindow::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        this->m_drag = true;
        this->dragPos = event->pos();
 
        this->resizeDownPos = event->globalPos();
        this->mouseDownRect = this->rect();
    }
}
 
void QFramelessWindow::mouseMoveEvent(QMouseEvent * event)
{
    if (resizeRegion != Default)
    {
        handleResize();
        return;
    }
    if(m_move) {
        move(event->globalPos() - dragPos);
        return;
    }
    QPoint clientCursorPos = event->pos();
    QRect r = this->rect();
    QRect resizeInnerRect(resizeBorderWidth, resizeBorderWidth, r.width() - 2*resizeBorderWidth, r.height() - 2*resizeBorderWidth);
    if(r.contains(clientCursorPos) && !resizeInnerRect.contains(clientCursorPos)) { //调整窗体大小
        ResizeRegion resizeReg = getResizeRegion(clientCursorPos);
        setResizeCursor(resizeReg);
        if (m_drag && (event->buttons() & Qt::LeftButton)) {
            resizeRegion = resizeReg;
            handleResize();
        }
    }
    else { //移动窗体
        setCursor(Qt::ArrowCursor);
        if (m_drag && (event->buttons() & Qt::LeftButton)) {
            m_move = true;
            move(event->globalPos() - dragPos);
        }
    }
}
 
void QFramelessWindow::mouseReleaseEvent(QMouseEvent *event)
{
    m_drag = false;
    if(m_move) {
        m_move = false;
        handleMove(event->globalPos()); //鼠标放开后若超出屏幕区域自动吸附于屏幕顶部/左侧/右侧
    }
    resizeRegion = Default;
    setCursor(Qt::ArrowCursor);
}
 
void QFramelessWindow::setResizeCursor(ResizeRegion region)
{
    switch (region)
    {
    case North:
    case South:
        setCursor(Qt::SizeVerCursor);
        break;
    case East:
    case West:
        setCursor(Qt::SizeHorCursor);
        break;
    case NorthWest:
    case SouthEast:
        setCursor(Qt::SizeFDiagCursor);
        break;
    default:
        setCursor(Qt::SizeBDiagCursor);
        break;
    }
}
 
ResizeRegion QFramelessWindow::getResizeRegion(QPoint clientPos)
{
    if (clientPos.y() <= resizeBorderWidth) {
        if (clientPos.x() <= resizeBorderWidth)
            return NorthWest;
        else if (clientPos.x() >= this->width() - resizeBorderWidth)
            return NorthEast;
        else
            return North;
    }
    else if (clientPos.y() >= this->height() - resizeBorderWidth) {
        if (clientPos.x() <= resizeBorderWidth)
            return SouthWest;
        else if (clientPos.x() >= this->width() - resizeBorderWidth)
            return SouthEast;
        else
            return South;
    }
    else {
        if (clientPos.x() <= resizeBorderWidth)
            return West;
        else
            return East;
    }
}
 
void QFramelessWindow::handleMove(QPoint pt)
{
    QPoint currentPos = pt - dragPos;
    if(currentPos.x()<desktop->x()) { //吸附于屏幕左侧
        currentPos.setX(desktop->x());
    }
    else if (currentPos.x()+this->width()>desktop->width()) { //吸附于屏幕右侧
        currentPos.setX(desktop->width()-this->width());
    }
    if(currentPos.y()<desktop->y()) { //吸附于屏幕顶部
        currentPos.setY(desktop->y());
    }
    move(currentPos);
}
 
void QFramelessWindow::handleResize()
{
    int xdiff = QCursor::pos().x() - resizeDownPos.x();
    int ydiff = QCursor::pos().y() - resizeDownPos.y();
    switch (resizeRegion)
    {
    case East:
    {
        resize(mouseDownRect.width()+xdiff, this->height());
        break;
    }
    case West:
    {
        resize(mouseDownRect.width()-xdiff, this->height());
        move(resizeDownPos.x()+xdiff, this->y());
        break;
    }
    case South:
    {
        resize(this->width(),mouseDownRect.height()+ydiff);
        break;
    }
    case North:
    {
        resize(this->width(),mouseDownRect.height()-ydiff);
        move(this->x(), resizeDownPos.y()+ydiff);
        break;
    }
    case SouthEast:
    {
        resize(mouseDownRect.width() + xdiff, mouseDownRect.height() + ydiff);
        break;
    }
    case NorthEast:
    {
        resize(mouseDownRect.width()+xdiff, mouseDownRect.height()-ydiff);
        move(this->x(), resizeDownPos.y()+ydiff);
        break;
    }
    case NorthWest:
    {
        resize(mouseDownRect.width()-xdiff, mouseDownRect.height()-ydiff);
        move(resizeDownPos.x()+xdiff, resizeDownPos.y()+ydiff);
        break;
    }
    case SouthWest:
    {
        resize(mouseDownRect.width()-xdiff, mouseDownRect.height()+ydiff);
        move(resizeDownPos.x()+xdiff, this->y());
        break;
    }
    }
}

本文的方案还附加了一个自动吸附功能,各位如果不需要的话,可以移除。

附上全局枚举及变量:

enum ResizeRegion
{
    Default,
    North,
    NorthEast,
    East,
    SouthEast,
    South,
    SouthWest,
    West,
    NorthWest
};
    bool m_drag, m_move;
    QPoint dragPos, resizeDownPos;
    const int resizeBorderWidth = 5;
    ResizeRegion resizeRegion;
    QRect mouseDownRect;


最后郑重提醒:别忘了在构造函数加上这句setMouseTracking(true); 切记切记!!!



FROM: http://blog.csdn.net/luols/article/details/48733721

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[Qt]不带标题栏(FramelessWindowHint)的窗体移动及调整大小 的相关文章

  • 从Qt5的改变看最佳头文件包含风格?QT5找不到#include头文件在哪里

    老版本 C C code 1 2 include
  • QT模态对话框

    下面来说说模态对话框 什么是模态对话框 所谓模态 就是在对话框弹出来之后 能够阻塞后面的窗口 Windows 上一般在退出时会弹出来一个问你是否保存的对话框 就是一个模态对话框 当它出现的时候 后面的窗口是不能点击的 必须要你关闭这个对话框
  • 在CXXLD libwebkitgtk-1.0.la时候发生 ld terminated with signal 9 [Killed]错误

    当时内存几乎用完了 发生这个错误是因为内存不够 编译不过来 系统是ubuntu 11 04 2G的物理内存不够 swap分区是1G CXXLD libwebkitgtk 1 0 la collect2 ld terminated with
  • Qt使用QSplitter实现分割窗口

    分割窗口在应用程序中经常用到 它可以灵活分布窗口布局 经常用于类似文件资源管理器的窗口设计中 然后抱着这样的想法简单的实现了下 cpp view plain copy print main cpp include
  • QWidget的背景颜色和背景图片的设置

    首先设置autoFillBackground属性为真 然后定义一个QPalette对象 设置QPalette对象的背景属性 颜色或图片 最后设置QWidget对象的Palette 实例 QWidget widget new QWidget
  • [Qt]不带标题栏(FramelessWindowHint)的窗体移动及调整大小

    Qt窗体若设置了 setWindowFlags Qt FramelessWindowHint 运行后该窗体是无法进行移动和调整大小的 那要如何才能让它和普通窗体一样进行移动和调整其大小的呢 方案如下 void QFramelessWindo
  • Qt之布局管理——停靠窗口

    QDockWidget类继承与QWidget类 用于停靠窗口的管理 在主窗口中 先设置中心控件 然后实例化QDockWidget对象 通过setFeatures 设置停靠窗口的窗体特性 通过 setAllowedAreas 设置窗体可停靠的
  • Qt动画效果展示

    在上一篇博文 Qt动画框架 原创翻译 中 我给大家原创翻译了Qt动画框架并且有文字和代码以及图片共同描述 今天在这篇博文中 主要实践Qt动画 做一个实例来讲解Qt动画使用 其界面如下图所示 由于没有录制为gif动画图片 所以请各位下载查看效
  • QT布局

    布局管理 以下是Qt手册中的 布局管理 的译文 在一个Widget中 Qt布局管理系统提供了一个简单而有效的方式来自动组织子widget 以保证他们能够很好地利用可用空间 介绍 Qt包含一个布局管理类的集合 它们被用来描述widgets如何
  • 数码相框实现遍历文件夹图片文件

    遍历文件夹图片文件 一 功能介绍 在为数码相框所在文件系统实现U盘自动挂载之后 将U盘自动挂载在开发板上文件系统中的 mnt usb目录 故还需为数码相框添加遍历 mnt usb路径下的文件夹内图片文件 暂定为扫描指定目录下一层文件夹内的图
  • qt的QLabel中的字体越界

    今天使用文泉驿的中文库wqy zenhei ttc 发现QLabel中的汉字上面切顶了 但是如果一个QLabel和一个QLineEdit并排就不会出现这种现象 最后对QLabel使用样式解决了这个问题 MyLabel gt setStyle
  • Qt之QTextEdit

    关于QTextEdit Qt5对Qt4的做了一些小的改动 看上去很多方法都发生了变化 但万变不离其中 如 槽函数setFontFamily const QFont 变为setFontFamily const QString fontFami
  • setFocus不能生效的问题

    focusInEvent只有在对象显示出来的情况下设定setFocus才可以触发 这一点help手册里有说明 转一篇文章如下 http blog csdn net alex201030273437 article details 81937
  • 重写QTabWidget,在标签后面添加图标按钮

    原本的QTabWidget没有支持在标签后面添加自定义的按钮的方法 想在后面添加自定义的功能按钮需要重写QTabWidget类 自己实现按钮图标的重绘和鼠标点击判断等操作 1 使用到的主要事件函数 1 void paintEvent QPa
  • Qt中图像的显示与基本操作

    Qt可显示基本的图像类型 利用QImage QPxmap类可以实现图像的显示 并且利用类中的方法可以实现图像的基本操作 缩放 旋转 1 Qt可显示的图像类型 参考Qt的帮助文档 可支持的类型 即可以直接读取并显示的格式有BMP GIF JP
  • Qt3.6.3编译pc版本的时候:collect2:ld terminated with signal 11

    Qt3 6 3编译pc版本的时候 collect2 ld terminated with signal 11 原因 是swap交换空间不够用 解决 扩大虚拟内存 具体参考下文 http hi baidu com seaeechou blog
  • QT中大connect的使用

    有时候为了测试方便 就直接在main函数中使用按钮的connect 但是必须添加QObject 否则会出错
  • Qt Resize与布局的冲突?

    问题的产生 我用QSplitter创建一个窗口布局之后 由于使用窗口默认初始大小 显示出来的比例不是很好看 因此调用了resize进行窗口大小的调整 调整之后是获得了想要的窗口大小 但是与此同时 却发现了一个问题 也就是经过resize之后
  • 【转】QT中QWS的含义

    QT编程和文档中的术语QWS的全称是Qt windows system 是QT自行开发的窗口系统 体系结构类似X Windows 是一个C S结构 由QWS Server在物理设备上显示 由QWS Client实现界面 两者通过socket
  • QString::arg() 函数

    例 setWindowTitle tr 1 2 arg shownName arg tr Spreadsheet QString arg 函数用第一个arg 调用会替换 1 第2个arg 调用会替换 2 上面的例子其实可以写作 setWin

随机推荐

  • dlp防泄密系统卸载_蓝盟IT外包聊聊:数据防泄密

    数字信息化的普遍应用使得企业信息泄露事件频发 根据调查显示 当今数据泄露事件中 90 的数据泄露是由于内部人员有意 无意的数据外泄行为所引发的 这种数据的泄露一旦发生对企业的打击可以说是致命的 数据防泄密已经成为企业信息安全非常重要的一部分
  • SpringBoot项目使用Sigar获取系统参数:CPU,内存,硬盘,网络流量波动

    先下载sigar http sigar hyperic com 将sigar bin lib目录下文件放到classpath中 1 pom
  • 淘宝框架atlas基本使用说明

    转自 http blog csdn net wdd1324 article details 76855408 官网 文档 github 视频资料 如有错误请指正 简介 Atlas是伴随着手机淘宝的不断发展而衍生出来的一个运行于Android
  • SOA是什么

    面向服务的体系结构 service oriented architecture SOA 是一个组件模型 它将应用程序的不同功能单元 称为服务 通过这些服务之间定义良好的接口和契约联系起来 接口是采用中立的方式进行定义的 它应该独立于实现服务
  • Java使用Hibernate-Validator验证API接口参数

    一 相关依赖
  • 逻辑地址 虚拟地址 物理地址 总线地址的区别

    1 逻辑地址 逻辑地址是最为模糊的概念 understanding the Linux kernel 上的解释是与虚拟地址相关 基于硬件MMU与软件内存管理的一个概念 具体可以看UTLK的第二章内存寻址 有很详细的解释 但是工作中之前用到的
  • 【2021-CVPR-3D人体姿态估计】Graph Stacked Hourglass Networks for 3D Human Pose Estimation

    Graph Stacked Hourglass Networks for 3D Human Pose Estimation 题目 用于3D人体姿态的图堆叠沙漏网络 作者 来源 CVPR 2021 研究内容 单人 单视图 有监督 创新点 提出
  • 目标检测数据集

    参考 You Only Look Once Unified Real Time Object Detection 你只看一次 统一的实时对象检测 CVPR 2016 1 PASCAL VOC PASCAL VOC 数据集是目标检测领域最常用
  • 推荐图灵出版社的图书

    最近半年买了不少图灵出版社的图书 有java oracle Linux和TCP IP方面的书 每本都读了差不多一半 读后有一种很亲切的感觉 总结下来一句话 很适合受中国传统教育的大部分学生 在此并无讽刺之意 很多学生习惯了 填鸭式 的教育模
  • 使用conda创建Python的虚拟环境

    目录 一 查看已有环境 二 创建虚拟环境 2 1 添加镜像地址 2 2 创建虚拟环境 2 3 激活虚拟环境 2 4 退出虚拟环境 三 pycharm使用环境 四 删除虚拟环境 五 快速创建虚拟环境 一 查看已有环境 键入以下命令 conda
  • nosql

    公共基础 一 NoSQL概述 1 NoSQL NoSQL定义 非关系型 分布式 开放源码和具有横向扩展能力的下一代数据库 NOSQL Not Only SQL 2 数据库的分类 1 TRDB数据库 传统关系型数据库 基于单机集中管理数据理念
  • 机器学习实战——第三章(分类):决策树算法与实例(一)

    前言 今天看了会 机器学习实战 第三章 决策树 很迷 似懂非懂 专业术语太多了 而且有点混乱 对于一个大一概率论没学好的学渣来说 如今大三的我看到那些概率公式和一些概率论专业术语就头疼 马上就打了退堂鼓 早起看了半个小时没看明白果断又躺回了
  • 设置swiper轮播图的css样式无效?

    项目场景 在做vue项目的时候 使用到了vue awesome swiper三方库 当时小编想重写 覆盖轮播图的分页器小圆点的css样式 其次 小编做项目时 使用的css预编译器是SCSS 问题描述 当小编在重写分页器小圆点css样式时 发
  • Vim配置及使用总结

    Vim配置及使用总结 我的Vim配置 Vim安装及配置文件 Vim安装 Vim配置文件 我的Vim配置 Vim配置详解 Vim使用技巧 基本使用介绍 命令模式 输入模式 底线命令模式 技巧总结 二进制文件查看 下面是我在使用vim时的一些配
  • Sass -- 条件语句、循环语句、自定义函数

    文章目录 条件语句 循环语句 for while each 自定义函数 条件语句 在Sass中可以使用 if if else if else 来进行条件判断 用法和JS相同 循环语句 在Sass中可以使用 for while each 来进
  • 4. Hadoop伪分布式运行模式

    文章目录 Hadoop伪分布式运行模式 1 启动HDFS并运行MapReduce程序 1 1 配置集群 配置hadoop env sh 配置core site xml 配置hdfs site xml 1 2 启动集群 格式化NameNode
  • window.open()的所有参数列表(转)

    前言 经常上网的朋友可能会到过这样一些网站 一进入首页立刻会弹出一个窗口 或者按一个连接或按钮弹出 通常在这个窗口里会显示一些注意事项 版权信息 警告 欢迎光顾之类的话或者作者想要特别提示的信息 其实制作这样的页面效果非常的容易 只要往该页
  • Python-玩转数据-Scrapy框架介绍及安装

    一 Scrapy框架说明 1 Scrapy介绍 Scrapy框架官方网址 http doc scrapy org en latest Scrapy是用纯Python实现一个为了爬取网站数据 提取结构性数据而编写的应用框架 用途非常广泛 用户
  • 如果访问云服务器上的文件,如果访问云服务器上的文件

    如果访问云服务器上的文件 内容精选 换一换 WinSCP工具可以实现在本地与远程计算机之间安全地复制文件 与使用FTP上传代码相比 通过 WinSCP 可以直接使用服务器账户密码访问服务器 无需在服务器端做任何配置 通常本地Windows计
  • [Qt]不带标题栏(FramelessWindowHint)的窗体移动及调整大小

    Qt窗体若设置了 setWindowFlags Qt FramelessWindowHint 运行后该窗体是无法进行移动和调整大小的 那要如何才能让它和普通窗体一样进行移动和调整其大小的呢 方案如下 void QFramelessWindo