自定义无边框窗口

效果: 可拖动拉伸

ui:设计如下

样式表:在ui CustomDialog 里设置的

                                        #widget_title{background: #E6F1EB;border-top-left-radius: 20px;border-top-right-radius: 20px;}#widget_client{background-color: rgb(255, 255, 255);border-bottom-left-radius: 20px; border-bottom-right-radius: 20px;}#label_title{background-color: #E6F1EB;font-family: Source Han Sans CN;font-size: 24px;font-weight: bold;}

头文件

#ifndef CUSTOMDIALOG_H
#define CUSTOMDIALOG_H#include <QDialog>
#include <QWidget>namespace Ui {
class CustomDialog;
}class CustomDialog : public QDialog
{Q_OBJECTpublic:explicit CustomDialog(QWidget *parent = nullptr);~CustomDialog();void setTitleText(const QString text);
private slots:void on_toolButton_quit_clicked();private:virtual void paintEvent(QPaintEvent *event) override; //重绘,virtual bool eventFilter(QObject *watched, QEvent *event);
private:Ui::CustomDialog *ui;int padding;                    //边距bool moveEnable;                //可移动bool resizeEnable;              //可拉伸bool pressed;                   //鼠标按下bool pressedLeft;               //鼠标按下左侧bool pressedRight;              //鼠标按下右侧bool pressedTop;                //鼠标按下上侧bool pressedBottom;             //鼠标按下下侧bool pressedLeftTop;            //鼠标按下左上侧bool pressedRightTop;           //鼠标按下右上侧bool pressedLeftBottom;         //鼠标按下左下侧bool pressedRightBottom;        //鼠标按下右下侧int rectX, rectY, rectW, rectH; //窗体坐标+宽高QPoint lastPos;                 //鼠标按下处坐标QRect rectLeft;                 //左侧区域QRect rectRight;                //右侧区域QRect rectTop;                  //上侧区域QRect rectBottom;               //下侧区域QRect rectLeftTop;              //左上侧区域QRect rectRightTop;             //右上侧区域QRect rectLeftBottom;           //左下侧区域QRect rectRightBottom;          //右下侧区域
};#endif // CUSTOMDIALOG_H

cpp

#include "customdialog.h"
#include "ui_customdialog.h"
#include <QStyleOption>
#include <QPainter>
#include <QMouseEvent>
CustomDialog::CustomDialog(QWidget *parent) :QDialog(parent),ui(new Ui::CustomDialog)
{ui->setupUi(this);setWindowFlags(Qt::FramelessWindowHint);setAttribute(Qt::WA_TranslucentBackground);//设置窗口透明化ui->toolButton_quit->setStyleSheet("QToolButton{border-radius: 20px;opacity: 1;""font-family: Source Han Sans CN;""font-size: 24px;""font-weight: norm;""background-color:#E6F1EB;}");padding = 8;moveEnable = true;resizeEnable = true;pressed = false;pressedLeft = false;pressedRight = false;pressedTop = false;pressedBottom = false;pressedLeftTop = false;pressedRightTop = false;pressedLeftBottom = false;pressedRightBottom = false;this->setMouseTracking(true);//绑定事件过滤器this->installEventFilter(this);//设置悬停为真,必须设置这个,不然当父窗体里边还有子窗体全部遮挡了识别不到MouseMove,需要识别HoverMovethis->setAttribute(Qt::WA_Hover, true);
}CustomDialog::~CustomDialog()
{delete ui;
}void CustomDialog::setTitleText(const QString text)
{ui->label_title->setText(text);
}void CustomDialog::paintEvent(QPaintEvent *)
{QStyleOption opt;opt.init(this);QPainter painter(this);style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);}bool CustomDialog::eventFilter(QObject *watched, QEvent *event)
{if (watched == this) {if (event->type() == QEvent::Resize) {//重新计算八个描点的区域,描点区域的作用还有就是计算鼠标坐标是否在某一个区域内int width = this->width();int height = this->height();//左侧描点区域rectLeft = QRect(0, padding, padding, height - padding * 2);//上侧描点区域rectTop = QRect(padding, 0, width - padding * 2, padding);//右侧描点区域rectRight = QRect(width - padding, padding, padding, height - padding * 2);//下侧描点区域rectBottom = QRect(padding, height - padding, width - padding * 2, padding);//左上角描点区域rectLeftTop = QRect(0, 0, padding, padding);//右上角描点区域rectRightTop = QRect(width - padding, 0, padding, padding);//左下角描点区域rectLeftBottom = QRect(0, height - padding, padding, padding);//右下角描点区域rectRightBottom = QRect(width - padding, height - padding, padding, padding);} else if (event->type() == QEvent::HoverMove) {//设置对应鼠标形状,这个必须放在这里而不是下面,因为可以在鼠标没有按下的时候识别QHoverEvent *hoverEvent = (QHoverEvent *)event;QPoint point = hoverEvent->pos();if (resizeEnable) {if (rectLeft.contains(point)) {this->setCursor(Qt::SizeHorCursor);} else if (rectRight.contains(point)) {this->setCursor(Qt::SizeHorCursor);} else if (rectTop.contains(point)) {this->setCursor(Qt::SizeVerCursor);} else if (rectBottom.contains(point)) {this->setCursor(Qt::SizeVerCursor);} else if (rectLeftTop.contains(point)) {this->setCursor(Qt::SizeFDiagCursor);} else if (rectRightTop.contains(point)) {this->setCursor(Qt::SizeBDiagCursor);} else if (rectLeftBottom.contains(point)) {this->setCursor(Qt::SizeBDiagCursor);} else if (rectRightBottom.contains(point)) {this->setCursor(Qt::SizeFDiagCursor);} else {this->setCursor(Qt::ArrowCursor);}}//根据当前鼠标位置,计算XY轴移动了多少int offsetX = point.x() - lastPos.x();int offsetY = point.y() - lastPos.y();//根据按下处的位置判断是否是移动控件还是拉伸控件if (moveEnable) {if (pressed) {this->move(this->x() + offsetX, this->y() + offsetY);}}if (resizeEnable) {if (pressedLeft) {int resizeW = this->width() - offsetX;if (this->minimumWidth() <= resizeW) {this->setGeometry(this->x() + offsetX, rectY, resizeW, rectH);}} else if (pressedRight) {this->setGeometry(rectX, rectY, rectW + offsetX, rectH);} else if (pressedTop) {int resizeH = this->height() - offsetY;if (this->minimumHeight() <= resizeH) {this->setGeometry(rectX, this->y() + offsetY, rectW, resizeH);}} else if (pressedBottom) {this->setGeometry(rectX, rectY, rectW, rectH + offsetY);} else if (pressedLeftTop) {int resizeW = this->width() - offsetX;int resizeH = this->height() - offsetY;if (this->minimumWidth() <= resizeW) {this->setGeometry(this->x() + offsetX, this->y(), resizeW, resizeH);}if (this->minimumHeight() <= resizeH) {this->setGeometry(this->x(), this->y() + offsetY, resizeW, resizeH);}} else if (pressedRightTop) {int resizeW = rectW + offsetX;int resizeH = this->height() - offsetY;if (this->minimumHeight() <= resizeH) {this->setGeometry(this->x(), this->y() + offsetY, resizeW, resizeH);}} else if (pressedLeftBottom) {int resizeW = this->width() - offsetX;int resizeH = rectH + offsetY;if (this->minimumWidth() <= resizeW) {this->setGeometry(this->x() + offsetX, this->y(), resizeW, resizeH);}if (this->minimumHeight() <= resizeH) {this->setGeometry(this->x(), this->y(), resizeW, resizeH);}} else if (pressedRightBottom) {int resizeW = rectW + offsetX;int resizeH = rectH + offsetY;this->setGeometry(this->x(), this->y(), resizeW, resizeH);}}} else if (event->type() == QEvent::MouseButtonPress) {//记住当前控件坐标和宽高以及鼠标按下的坐标QMouseEvent *mouseEvent = (QMouseEvent *)event;rectX = this->x();rectY = this->y();rectW = this->width();rectH = this->height();lastPos = mouseEvent->pos();//判断按下的手柄的区域位置if (rectLeft.contains(lastPos)) {pressedLeft = true;} else if (rectRight.contains(lastPos)) {pressedRight = true;} else if (rectTop.contains(lastPos)) {pressedTop = true;} else if (rectBottom.contains(lastPos)) {pressedBottom = true;} else if (rectLeftTop.contains(lastPos)) {pressedLeftTop = true;} else if (rectRightTop.contains(lastPos)) {pressedRightTop = true;} else if (rectLeftBottom.contains(lastPos)) {pressedLeftBottom = true;} else if (rectRightBottom.contains(lastPos)) {pressedRightBottom = true;} else {pressed = true;}} else if (event->type() == QEvent::MouseMove) {//改成用HoverMove识别} else if (event->type() == QEvent::MouseButtonRelease) {//恢复所有pressed = false;pressedLeft = false;pressedRight = false;pressedTop = false;pressedBottom = false;pressedLeftTop = false;pressedRightTop = false;pressedLeftBottom = false;pressedRightBottom = false;this->setCursor(Qt::ArrowCursor);}}return QObject::eventFilter(watched, event);
}void CustomDialog::on_toolButton_quit_clicked()
{reject();
}

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

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

相关文章

房产中介租房小程序系统开发搭建

随着移动互联网的发展&#xff0c;租房小程序已经成为许多房产中介公司转型线上的重要工具。通过租房小程序&#xff0c;房产中介公司可以方便地展示房源信息、吸引租户、达成交易。那么&#xff0c;如何通过乔拓云网开发租房小程序呢&#xff1f;下面是详细的开发指南。 1.进入…

Linux Centos7 下使用yum安装的nginx平滑升级

1. 查看当前nginx版本 1nginx -v2. 查看centos版本 1cat /etc/redhat-release3. 创建一个新的文件nginx.repo&#xff0c;其中第三行的7是因为我的centos版本是7点多的&#xff0c;你看自己是多少就改多少 1vim /etc/yum.repos.d/nginx.repo23[nginx]4namenginx repo 5baseu…

区块链游戏的开发流程

链游&#xff08;Blockchain Games&#xff09;的开发流程与传统游戏开发有许多相似之处&#xff0c;但它涉及到区块链技术的集成和智能合约的开发。以下是链游的一般开发流程&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&…

STM32--WDG看门狗

文章目录 WDG简介IWDGIWDG的超时计算WWDGWWDG超时和窗口值设定独立看门狗工程WWDG工程 WDG简介 WDG看门狗&#xff08;Watchdog Timer&#xff09;是一种常见的硬件设备&#xff0c;在STM32F10系列中&#xff0c;有两种看门狗&#xff0c;分别是独立看门狗和窗口看门狗&#x…

Jetson Orin NX 开发指南(8): Mavros 的安装与配置

一、前言 由于 Jetson 系列开发板常作为自主无人机的机载电脑&#xff0c;而无人机硬件平台如 PX4 和 ArduPilot 等通过 MAVLink 进行发布无人机状态和位姿等信息&#xff0c;要实现机载电脑与 MAVLink 的通信&#xff0c;必须借助 Mavros 功能包&#xff0c;因此&#xff0c;…

uniapp EventChannel 页面跳转参数事件传递navigateBack,navigateTo 成功后通知事件区别

问题&#xff1a;navigateBack&#xff08;&#xff09;emit事件在onload()监听不到 从A页面跳转到B页面&#xff0c;在B点击产生数据后&#xff0c;跳转回到A&#xff0c;并告诉A点击的数据是什么&#xff0c;使用&#xff1a; navigateBack&#xff08;&#xff09;。 &…

Vue3 + Nodejs 实战 ,文件上传项目--实现图片上传

目录 技术栈 1. 项目搭建前期工作(不算太详细) 前端 后端 2.配置基本的路由和静态页面 3.完成图片上传的页面&#xff08;imageUp&#xff09; 静态页面搭建 上传图片的接口 js逻辑 4.编写上传图片的接口 5.测试效果 结语 博客主页&#xff1a;専心_前端,javascript,mys…

UTF-8的编码与解码

文章目录 一、什么是unicode二、什么是编码三、.unicode和utf-8编码是什么关系四、示例五、编码规则是什么 一、什么是unicode UNICDOE是一个字符集&#xff0c;它定义了世界上所有字符的唯一编号&#xff0c;每一个字符编号称为码点 详细参考- https://www.cnblogs.com/Illid…

【【萌新的SOC学习之GPIO之MIO控制LED实验程序设计】】

萌新的SOC学习之GPIO之MIO控制LED实验程序设计 如何设置完GPIO并且传递数据 我们先了解GPIO引脚的配置 每一个GPIO引脚都可以设置成输入输出 &#xff0c;只有GPIO8 7 只能作为输出 我们现在做一个例子 GPIO 的bank我们知道有4个 bank0 1 2 3 DIRM_0 就是第一个bank 需要写入…

如何压缩视频?视频压缩变小方法汇总

视频是我们日常生活中不可或缺的一部分&#xff0c;但视频文件往往会占用大量存储空间&#xff0c;这在传输和分享过程中可能成为一个瓶颈。 为了解决这一问题&#xff0c;我们可以通过压缩的方式减小视频大小&#xff0c;视频压缩是指在保证视频质量的前提下&#xff0c;通过…

【Debian系统】:安装debian系统之后,很多命令找不到,需要添加sudo之后才能使用,以下解决方法

项目场景&#xff1a; 问题描述 解决方案&#xff1a; 1.临时解决方案 2.永久解决方案 1.首先打开编辑&#xff1a; 2.打开之后最后一行添加代码&#xff1a; 3.最后运行一遍 .bashrc 4.已经可以了&#xff0c;可以试试reboot&#xff0c;重启一下机子 一点一滴才能成长 …

Mysql5.7大限将至升级Mysql 8.0过程记录(未完)

一、前言 时间很快&#xff0c;到2023年10月底&#xff0c;MySQL 5.7就到了它的EOL&#xff08;End of Life&#xff09;&#xff0c;届时将不会提供任何补丁&#xff0c;无法应对潜在的安全风险&#xff1b;是时候和 MySQL 5.7 说再见了&#xff01;&#xff01;&#xff01;&…