Qt C++ 实现无边框窗口

Qt C++ 实现无边框窗口

// widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QDebug>
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QPushButton>
#include <QString>
#include <QWidget>#define PADDING 6enum Location {TOP,BOTTOM,LEFT,RIGHT,TOP_LEFT,TOP_RIGHT,BOTTOM_LEFT,BOTTOM_RIGHT,CENTER
};class Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget* parent = nullptr);~Widget();protected:void mousePressEvent(QMouseEvent* event);void mouseMoveEvent(QMouseEvent* event);void mouseReleaseEvent(QMouseEvent* event);private:void setCursorShape(const QPoint& point);private:// 左键有没有按下bool isLeftPressed;// 鼠标按下的位置 偏移QPoint mouseOffset;Location location;
};
#endif  // WIDGET_H
// widget.cpp
#include "widget.h"Widget::Widget(QWidget* parent) : QWidget(parent) {// 设置窗口的宽高this->setMinimumWidth(500);this->setMinimumHeight(300);// 设置背景色this->setStyleSheet("background: #303030");// 添加两个按钮 - 水平布局QHBoxLayout* layout = new QHBoxLayout(this);layout->setSpacing(10);layout->setContentsMargins(10, 10, 10, 10);QPushButton* btn1 = new QPushButton("确定");QPushButton* btn2 = new QPushButton("取消");layout->addWidget(btn1);layout->addWidget(btn2);QString style = R"(QPushButton {background-color: rgb(64, 64, 64);font: 16px "Microsoft YaHei";color: rgb(200, 200, 200);border-radius: 5px;padding: 5px;}QPushButton:hover {background-color: rgb(40, 40, 40);}QPushButton:pressed {background-color: rgb(64, 64, 64);})";btn1->setStyleSheet(style);btn2->setStyleSheet(style);// 去除标题栏this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);this->isLeftPressed = false;// 开启鼠标追踪this->setMouseTracking(true);
}Widget::~Widget() {}void Widget::mousePressEvent(QMouseEvent* event) {switch (event->button()) {case Qt::RightButton:this->close();break;case Qt::LeftButton:this->isLeftPressed = true;if (location == CENTER) {this->mouseOffset =event->globalPos() - this->frameGeometry().topLeft();}break;}
}void Widget::mouseMoveEvent(QMouseEvent* event) {QPoint globalPos = event->globalPos();QRect rect = this->rect();QPoint topLeft = mapToGlobal(rect.topLeft());QPoint bottomRight = mapToGlobal(rect.bottomRight());// 1. 鼠标未按下if (!this->isLeftPressed) {this->setCursorShape(globalPos);return;}// 2. 鼠标按下, 在CENTER位置按下if (this->location == CENTER) {move(globalPos - mouseOffset);event->accept();return;}// 3. 缩放QRect rMove(topLeft, bottomRight);switch (location) {case TOP:// 窗口达到最小高度后,会被鼠标 “向下推走”if (bottomRight.y() - globalPos.y() > this->minimumHeight())rMove.setY(globalPos.y());break;case BOTTOM:rMove.setHeight(globalPos.y() - topLeft.y());break;case LEFT:if (bottomRight.x() - globalPos.x() > this->minimumWidth())rMove.setX(globalPos.x());break;case RIGHT:rMove.setWidth(globalPos.x() - topLeft.x());break;case TOP_LEFT:if (bottomRight.y() - globalPos.y() > this->minimumHeight())rMove.setY(globalPos.y());if (bottomRight.x() - globalPos.x() > this->minimumWidth())rMove.setX(globalPos.x());break;case TOP_RIGHT:if (bottomRight.y() - globalPos.y() > this->minimumHeight())rMove.setY(globalPos.y());rMove.setWidth(globalPos.x() - topLeft.x());break;case BOTTOM_LEFT:rMove.setHeight(globalPos.y() - topLeft.y());if (bottomRight.x() - globalPos.x() > this->minimumWidth())rMove.setX(globalPos.x());break;case BOTTOM_RIGHT:rMove.setHeight(globalPos.y() - topLeft.y());rMove.setWidth(globalPos.x() - topLeft.x());break;default:break;}this->setGeometry(rMove);
}void Widget::mouseReleaseEvent(QMouseEvent* event) {if (event->button() == Qt::LeftButton) {isLeftPressed = false;}
}void Widget::setCursorShape(const QPoint& point) {QRect rect = this->rect();QPoint topLeft = mapToGlobal(rect.topLeft());QPoint bottomRight = mapToGlobal(rect.bottomRight());int x = point.x();int y = point.y();if (x >= topLeft.x() && x <= topLeft.x() + PADDING && y >= topLeft.y() &&y <= topLeft.y() + PADDING) {// 左上角location = TOP_LEFT;this->setCursor(QCursor(Qt::SizeFDiagCursor));} else if (x <= bottomRight.x() && x >= bottomRight.x() - PADDING &&y <= bottomRight.y() && y >= bottomRight.y() - PADDING) {// 右下角location = BOTTOM_RIGHT;this->setCursor(QCursor(Qt::SizeFDiagCursor));} else if (x >= topLeft.x() && x <= topLeft.x() + PADDING &&y <= bottomRight.y() && y >= bottomRight.y() - PADDING) {// 左下角location = BOTTOM_LEFT;this->setCursor(QCursor(Qt::SizeBDiagCursor));} else if (x <= bottomRight.x() && x >= bottomRight.x() - PADDING &&y >= topLeft.y() && y <= topLeft.y() + PADDING) {// 右上角location = TOP_RIGHT;this->setCursor(QCursor(Qt::SizeBDiagCursor));} else if (x >= topLeft.x() && x <= topLeft.x() + PADDING) {// 左边location = LEFT;this->setCursor(QCursor(Qt::SizeHorCursor));} else if (x >= bottomRight.x() - PADDING && x <= bottomRight.x()) {// 右边location = RIGHT;this->setCursor(QCursor(Qt::SizeHorCursor));} else if (y >= topLeft.y() && y <= topLeft.y() + PADDING) {// 上边location = TOP;this->setCursor(QCursor(Qt::SizeVerCursor));} else if (y >= bottomRight.y() - PADDING && y <= bottomRight.y()) {// 下边location = BOTTOM;this->setCursor(QCursor(Qt::SizeVerCursor));} else {location = CENTER;this->setCursor(QCursor(Qt::ArrowCursor));}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/818753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SoC的启动流程 和MCU的启动流程 有什么区别?

SoC&#xff08;System on Chip&#xff09;和MCU&#xff08;Microcontroller Unit&#xff09;的启动流程在很多方面是相似的&#xff0c;因为它们都涉及到硬件的初始化和软件的加载。然而&#xff0c;由于SoC通常包含更复杂的系统集成和可能运行更高级的操作系统&#xff0c…

HLS视频播放在iOS和安卓平台的适配问题及解决方案

HLS视频播放在iOS和安卓平台的适配问题及解决方案 在移动端视频播放中&#xff0c;HLS&#xff08;HTTP Live Streaming&#xff09;是一种常用的流媒体传输协议&#xff0c;可以实现视频的分段传输和自适应码率调整&#xff0c;以提供更好的播放体验。然而&#xff0c;由于iO…

获取字符串的全排列(去除字符串中2个字符相同时造成的重复)

一、概念 现有一个字符串&#xff0c;要打印出该字符串中字符的全排列。 以字符串abc为例&#xff0c;输出的结果为&#xff1a;abc、acb、bac、bca、cab、cba。 以字符串aab为例&#xff0c;输出的结果为&#xff1a;aab、aba、baa。 二、代码 public class Permutation {pub…

Rabbitmq中的延迟队列是什么?有什么作用?如何使用?

1、Rabbitmq中的延迟队列是什么&#xff1f; 在RabbitMQ中&#xff0c;延迟队列是一个特殊的队列&#xff0c;用于存放需要在指定时间后被处理的消息。这种队列的主要特性是它可以为队列中的每个消息设置一定的延迟时间&#xff0c;只有在延迟时间到达后&#xff0c;消息才会被…

【Linux】Linux基础与常用指令大全

文章目录 操作系统是什么&#xff1f;1. Linux家族介绍2. Linux的安装方式3. 常用指令3.1 ls [选项] [目录/文件]&#xff08;显示目录或文件信息&#xff09;3.2 pwd&#xff08;显示当前所在目录&#xff09;3.3 任意指令加上 --help&#xff08;查看指令的用法&#xff09;3…

ThinkPHP V5.1框架源码

源码下载地址&#xff1a;ThinkPHP V5.1.zip www WEB部署目录&#xff08;或者子目录&#xff09; ├─application 应用目录 │ ├─common 公共模块目录&#xff08;可以更改&#xff09; │ ├─module_name 模块目录 │ │ ├─common.php 模块函数文件 │ │ ├─controll…

一文掌握 React 开发中的 JavaScript 基础知识

前端开发中JavaScript是基石。在 React 开发中掌握掌握基础的 JavaScript 方法将有助于编写出更加高效、可维护的 React 应用程序。 在 React 开发中使用 ES6 语法可以带来更简洁、可读性更强、功能更丰富,以及更好性能和社区支持等诸多好处。这有助于提高开发效率,并构建出更…

线性表概念及顺序表的实现

文章目录 前言一、线性表1.定义2.特点3.一般线性表的抽象数据类型定义 二、线性表的顺序存储&#xff08;顺序表&#xff09;1.基本概念2.数组实现顺序表3.顺序表中基本操作的具体实现4.顺序表总结 总结 前言 T_T此专栏用于记录数据结构及算法的&#xff08;痛苦&#xff09;学…

MyBatis 源码分析系列文章导读

1.本文速览 本篇文章是我为接下来的 MyBatis 源码分析系列文章写的一个导读文章。本篇文章从 MyBatis 是什么&#xff08;what&#xff09;&#xff0c;为什么要使用&#xff08;why&#xff09;&#xff0c;以及如何使用&#xff08;how&#xff09;等三个角度进行了说明和演…

vue--数据代理与数据劫持

0.回顾Object.defineProperty()方法 let number 18let person {name:张三,sex:男,}Object.defineProperty(person,age,{// value:18,// enumerable:true, //控制属性是否可以枚举&#xff0c;默认值是false// writable:true, //控制属性是否可以被修改&#xff0c;默认值是fa…

通义灵码×西安交通大学携手打造“云工开物-高校训练营”,解锁 AI 时代编程学习与实战

作为大学生如何利用 AI “整活儿”&#xff1f;欢迎各位同学关注阿里云与西安交通大学计算机学院携手打造的“云工开物-高校训练营”&#xff0c;带你走近 AI 编程助手“通义灵码”。通义灵码是阿里推出的免费 AI 编程工具&#xff0c;拥有实时代码续写与优化、自然语言生成代码…

记一次对某高校微信小程序的漏洞挖掘

挖掘目标的部署在微信的资产(减少信息的收集&#xff0c;毕竟一般web站点没有账号密码不好进入后台&#xff0c;挖掘功能点少) 寻找目标的微信小程序(非原图) 招生小程序打不开&#xff0c;只能挖掘管理系统 进入后发现存在上报安全隐患功能&#xff0c;可以上传图片 准备上传…

浅谈Java21的新特性-虚拟线程

虚拟线程&#xff08;Virtual Threads&#xff09;&#xff0c;又称为用户模式线程&#xff08;User-Mode Threads&#xff09;或纤程&#xff08;Fibers&#xff09;&#xff0c;是一种高级线程模型&#xff0c;在Java等现代编程语言环境中引入&#xff0c;旨在简化并发编程并…

Vue的图片懒加载 vue-lazyload插件使用

图片懒加载是一种网页性能优化技术&#xff0c;页面加载时仅加载可见区域内的图像&#xff0c;图像只会在用户滚动或浏览到它们时才会被加载&#xff0c;而不是在页面一开始就全部加载。 优点 可以减少首页首次加载的数量&#xff0c;减少服务器的压力有占位图片来展示预加载动…

【面经】操作系统/Linux

1、计算机的五大单元 电脑的五大单元包括&#xff1a;输入单元、输出单元、控制单元、算数逻辑单元、存储单元五大部分。其中CPU占有控制、算术逻辑单元&#xff0c;存储单元又包含内存与辅助内存&#xff1b; 2、什么是操作系统 操作系统&#xff1a;负责管理协调我们计算机…

Qt QStyle详解

1.简介 QStyle类是 Qt 框架中用于控制应用程序界面元素外观的一个抽象基类。这个类提供了一种方式来定制窗口部件&#xff08;widgets&#xff09;的绘制和行为&#xff0c;可以通过改变主题或风格来更改应用程序的外观&#xff0c;而无需修改窗口部件本身的代码。 Qt包含一组…

python爬虫------- Selenium下篇(二十三天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

剑指offer03:数组中重复的数组---leetcode:LCR 120. 寻找文件副本

设备中存有 n 个文件&#xff0c;文件 id 记于数组 documents。若文件 id 相同&#xff0c;则定义为该文件存在副本。请返回任一存在副本的文件 id。 示例 1&#xff1a; 输入&#xff1a;documents [2, 5, 3, 0, 5, 0] 输出&#xff1a;0 或 5提示&#xff1a; 0 ≤ docume…

Python中的定长参数和不定长参数:深入理解与应用

文章目录 1. 定长参数的基本使用2. 不定长参数的基本使用2.1 *args 的使用2.2 **kwargs 的使用 3. 参数的混合使用4. 参数的应用实例4.1 数据处理示例4.2 事件处理示例小彩蛋... 函数参数的灵活处理是编写高效、可读性强的代码的关键。下面将详细介绍定长参数和不定长参数的使用…

【代码随想录算法训练营第四十八天 | LeetCode198.打家劫舍、213.打家劫舍II、337.打家劫舍III】

代码随想录算法训练营第四十八天 | LeetCode198.打家劫舍、213.打家劫舍II、337.打家劫舍III 一、198.打家劫舍 解题代码C&#xff1a; class Solution { public:int rob(vector<int>& nums) {if (nums.size() 0) return 0;if (nums.size() 1) return nums[0];ve…