当前位置: 首页 > news >正文

自定义无边框窗口

效果: 可拖动拉伸

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.lryc.cn/news/187079.html

相关文章:

  • 【网络安全 --- kali2023安装】超详细的kali2023安装教程(提供镜像资源)
  • 机器学习笔记(二)
  • Java @Override 注解
  • 用rabbitMq 怎么处理“延迟消息队列”?
  • 不常见的JS加密分析
  • TCP原理特性详解
  • 什么是懒加载,JS如何实现懒加载,在php中如何去实现懒加载
  • Cesium 展示——读取文件——加载 geojson 文件数据
  • (二)Apache log4net™ 手册 - 配置
  • Elasticsearch:时间点 API
  • hive数据表定义
  • OpenMesh 网格简化之顶点聚类
  • C++ 类和对象篇(八) const成员函数和取地址运算符重载
  • k8s 集群安装(vagrant + virtualbox + CentOS8)
  • 8、Docker数据卷与数据卷容器
  • 大数据与Hadoop入门理论
  • 持续集成部署-k8s-深入了解 Pod:探针
  • 来单提醒/客户催单 ----苍穹外卖day9
  • 【单片机】18-红外线遥控
  • 【Node.js】module 模块化
  • Vue中如何进行分布式日志收集与日志分析(如ELK Stack)
  • java学习--day23(线程池)
  • Unity Golang教程-Shader编写一个流动的云效果
  • Python数据攻略-Pandas与地理空间数据分析
  • sourceTree无法启动
  • 【ARM Coresight 系列文章19 -- Performance Monitoring Unit(性能监测单元)
  • 前端学习| 第二章
  • Unity中Shader光强与环境色
  • Android9 查看连接多个蓝牙耳机查看使用中的蓝牙耳机
  • 【EF Core】如何忽略影响导航属性(级联)