使用QT 开发不规则窗体

使用QT 开发不规则窗体

  • 不规则窗体
  • 贴图法的不规则窗体
    • 创建UI模板
    • 创建一个父类
    • 创建业务窗体
    • main函数直接调用user_dialog
    • 创建QSS文件
  • 完整的QT工程

不规则窗体

QT中开发不规则窗体有两种方法:(1)第一种方法,使用QWidget::setMask函数设置绘制区域,然后在paintEvent()绘制。(2)第二种方法,在窗体四周设置一圈QWidget,设置一些不规则的图片,达到不规则窗体的目的。本次介绍贴图的这种方法。

贴图法的不规则窗体

创建UI模板

在QT中创建一个UI窗体。
在这里插入图片描述

在上下左右不同的区域设置QWidget:(1)上方:左上角,右上角,上方正中是标题栏;(2)下方:左下角,下方正中,右下角。(3)窗体两侧(4)窗体正中是业务窗体的窗体,业务窗体下方放置两按钮【确定】【取消】

运行效果图:

在这里插入图片描述

创建一个父类

创建一个父类,用于显示不规则窗体的四周,以后的窗体就不用重新作,直接继承就可以了。为了简捷,就不用cpp,把代码直接写到头文件里。

#ifndef CUSTOM_DIALOG_BASE_H
#define CUSTOM_DIALOG_BASE_H

#include <QDialog>
#include <QDesktopWidget> 
#include <QApplication>
#include <QMouseEvent> 
#include <QDebug> 
#include <QKeyEvent> 
#include "ui_custom_dialog_base.h"
class custom_dialog_base : public QDialog
{
    Q_OBJECT

public:
    explicit custom_dialog_base(QWidget *parent = 0)
    {
        setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::Dialog);//无边框
        this->setAttribute(Qt::WA_TranslucentBackground, true);//窗体背景全透明
        ui.setupUi(this);
        m_bMouseLeftButtonPressed = false;
        m_bCtrlKeyPressed = false;

        connect(ui.pushButton_close, &QPushButton::clicked, this, &QDialog::close);

        connect(ui.pushButton_ok, &QPushButton::clicked, this, &QDialog::accept);

        connect(ui.pushButton_cancel, &QPushButton::clicked, this, &QDialog::reject);

        ui.label_title->installEventFilter(this);

    }

    ~custom_dialog_base(){};

    // 居中在父窗体中
    void centerParent()
    {
        QWidget* parentWidget = this->parentWidget();
        QRect rect = this->geometry();
        QRect rectParent;
        if(parentWidget != nullptr)
        {
            rectParent = parentWidget->geometry();
        }
        else
        {
            rectParent = QApplication::desktop()->geometry();
        }
        QPoint center = rectParent.center();
        int width = rect.width();
        int height = rect.height();
        this->setGeometry(center.x()-width/2, center.y() - height/2, width, height);
    }

     // 设置标题
    void setDialogTitle(const QString& strTitle)
    {
        ui.label_title->setText(strTitle);
    }
    //获取中间的内容面板
    QWidget* getContainerWidget() { return ui.inner_frame;  }

protected:
    // ctrl键按下
    virtual void  keyPressEvent(QKeyEvent *event)
    {
        if (event->key() &Qt::Key_Control)
        {
            m_bCtrlKeyPressed = true;
            this->setSizeGripEnabled(true);// ctrl键按下,显示窗体缩放抓手。
        }
    }

    // ctrl键松开
    virtual void  keyReleaseEvent(QKeyEvent *event)
    {
        if (event->key() &Qt::Key_Control)
        {
            m_bCtrlKeyPressed = false;
            this->setSizeGripEnabled(false);
        }
    }

    // 窗体移动实现
    bool eventFilter(QObject *obj, QEvent *event)
    {
         // ctrl键按下时返回
        if (m_bCtrlKeyPressed)
        {
            return false;
        }

        // 判断是标题栏
        if (obj == ui.label_title)
        {
            //鼠标左键按下
            if (event->type() == QEvent::MouseButtonPress)
            {
                m_bMouseLeftButtonPressed = true;
                m_pointMouseLeftButtonPressed = QCursor::pos();
                return true;
            }
            else if (event->type() == QEvent::MouseButtonRelease)
            {//鼠标左键松开
                m_bMouseLeftButtonPressed = false;
                return true;
            }
            else if (event->type() == QEvent::MouseMove && m_bMouseLeftButtonPressed)
            {//鼠标左键按下时移动鼠标,开始移动窗体
                QPoint offset = QCursor::pos() - m_pointMouseLeftButtonPressed;
                QPoint pos = this->pos();
                this->move(offset + pos);
                m_pointMouseLeftButtonPressed = QCursor::pos();
                return true;
            }
        }

        return false;
    }

private:
    Ui_custom_dialog_base ui;

    //鼠标是否按下
    bool m_bMouseLeftButtonPressed;

    //cltr键是否按下
    bool m_bCtrlKeyPressed;

    //按下后当前鼠标位置
    QPoint m_pointMouseLeftButtonPressed;
};
// 可以pro文件中加入custom_dialog_base.h,不要下句
#include "./moc/moc_custom_dialog_base.cpp"

#endif // CUSTOM_DIALOG_BASE_H

创建业务窗体

业务窗体直接继承custom_dialog_base 类。同样,把cpp省去。把代码直接写到头文件里。

#ifndef USER_DIALOG_H
#define USER_DIALOG_H

#include <QDialog>
#include <QDesktopWidget> 
#include <QApplication>
#include <QMouseEvent> 
#include <QDebug> 
#include <QKeyEvent> 
#include "ui_user_dialog.h"
#include "custom_dialog_base.h"

class user_dialog : public custom_dialog_base
{
    Q_OBJECT

public:
    explicit user_dialog(QWidget *parent = 0)
    {
        ui.setupUi(getContainerWidget());// 加载业务窗体,
        getContainerWidget()->setLayout(ui.formLayout_2);// 设置业务窗体的布局器到父类中的容器中。
        ui.formLayout_2->setSpacing(15);
    }

    ~user_dialog(){};

private:
    Ui_user_dialog ui;
};

// 可以在pro文件中加入user_dialog.h,不要下句
#include "./moc/moc_user_dialog.cpp"
#endif // USER_DIALOG_H

main函数直接调用user_dialog

在main里直接创建user_dialog的实例,显示不规则窗体。

#include <QApplication>
#include <QDir>
#include <QPushButton>
#include "user_dialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
	QFile file;
    QString strFile = QDir(QApplication::applicationDirPath()).canonicalPath() + "/ui.qss";
	file.setFileName(strFile);
	file.open(QFile::ReadOnly);
	file.seek(0);
    QString strQss= file.readAll();// 从ui.qss文件中读取样式
    a.setStyleSheet(strQss); // 设置样式
	user_dialog dlg;
    dlg.setDialogTitle(QString::fromLocal8Bit("窗体标题"));
    dlg.centerParent();// 居中父窗体。
    return dlg.exec();
}

创建QSS文件

把使用自己喜欢的图片放到资源文件中,供QSS文件使用。

qss文件:


QWidget#widget_topleft{
	background-color:transparent;
	border-image:url(:/resources/top_left.png);
}

QWidget#widget_topcenter{
	background-color:transparent;
	border-image:url(:/resources/top_center.png);
}

QWidget#widget_topright{
	background-color:transparent;
	border-image:url(:/resources/top_right.png);
}


QWidget#widget_bottomleft{
	background-color:transparent;
	border-image:url(:/resources/bottom_left.png);
}

QWidget#widget_bottom_center{
	background-color:transparent;
	border-image:url(:/resources/bottom_center.png);
}


QWidget#widget_bottomright{
	background-color:transparent;
	border-image:url(:/resources/bottom_right.png);
}



QWidget#widget_left{
	background-color:transparent;
	border-image:url(:/resources/left_center.png);
}

QWidget#widget_center{
	background-color:transparent;
	border-image:url(:/resources/center.png);
}


QWidget#widget_right{
	background-color:transparent;
	border-image:url(:/resources/right_center.png);
}

QPushButton#pushButton_close{
	background-color: transparent;
	background-image:url(:/resources/pushButton_close.png);
}

QLabel{
	font-size:16px;
	color:white;
}
QLabel#label_title{
	background-color: transparent;
    text-align: center;
	font-size:18px;
	color:white;
}


QLineEdit, QComboBox,QDateTimeEdit,QSpinBox {
	font-size:18px;
}

QSizeGrip {
      image: url(:/resources/resize_gripper.png);
      width: 32px;
      height: 32px;
  }

QPushButton#pushButton_ok,QPushButton#pushButton_cancel {
	background-color: transparent;
	border-image:url(:/resources/pushbutton.png);
	min-width:96px;
	min-height:32px;
}


QPushButton#pushButton_ok:pressed,QPushButton#pushButton_cancel:pressed {
	background-color: transparent;
	border-image:url(:/resources/pushbutton_pressed.png);
}


QPushButton#pushButton_ok:hover,QPushButton#pushButton_cancel:hover {
	background-color: transparent;
	border-image:url(:/resources/pushbutton_hover.png);
}

qrc文件:

<RCC>
    <qresource prefix="/">
        <file>./resources/top_left.png</file>
        <file>./resources/top_center.png</file>
        <file>./resources/top_right.png</file>
        <file>./resources/left_center.png</file>
        <file>./resources/center.png</file>
        <file>./resources/right_center.png</file>
        <file>./resources/bottom_left.png</file>
        <file>./resources/bottom_center.png</file>
        <file>./resources/bottom_right.png</file>
        <file>./resources/pushButton_close.png</file>
        <file>./resources/resize_gripper.png</file>
        <file>./resources/pushbutton.png</file>
        <file>./resources/pushbutton_pressed.png</file>
        <file>./resources/pushbutton_hover.png</file>
    </qresource>
</RCC>

完整的QT工程

工程文件下载,不完善之处,老铁们一块讨论。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

川土微高性能模拟芯片系列产品介绍和应用

一、公司简介 上海川土微电子有限公司是一家成立于2016年的专注于高端模拟芯片研发设计与销售的高科技公司&#xff0c;产品涵盖隔离与接口、驱动与电源、高性能模拟三大产品线以及μMiC战略产品&#xff08; micro-Module in Chip&#xff09;。目前产品已广泛应用于工业控制…

怎么在SU草图大师里做地形模型?

​​​​​​  1.导入地形数据&#xff1a;首先&#xff0c;找到你想要模拟的地形数据。常见的文件格式是DEM(数字高程模型)文件&#xff0c;它包含地表高程数据。在SketchUp中&#xff0c;通过菜单栏选择“文件” -> “导入” -> “DEM”&#xff0c;然后选择你的DEM文…

基于springboot实现桂林旅游景点导游平台管理系统【项目源码+论文说明】

基于springboot实现桂林旅游景点导游平台管理系统演示 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了桂林旅游景点导游平台的开发全过程。通过分析桂林旅游景点导游平台管理的不足&#xff0c;创建了一个计算…

【数据结构(四)】链表经典练习题

❣博主主页: 33的博客❣ ▶️文章专栏分类:数据结构◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你学更多数据结构知识 目录 1.前言2.删除值为key的所有结点3.反转链表4.返回中间结点5.输出倒数第k个结点6.链表…

2024-04-10 Linux gzip 和 gunzip 命令,gzip 压缩的文件通常比原始文件小得多。

一、gzip 是 Linux 系统中用于压缩文件的命令&#xff0c;它通常用于将单个文件压缩成 .gz 格式的文件。gzip 压缩的文件通常比原始文件小得多&#xff0c;因此它在节省磁盘空间和减少文件传输时间方面非常有用。 gzip 命令的基本语法如下&#xff1a; gzip [选项] [文件]复制…

VMware vSphere Hypervisor,ESXi的介绍,下载与安装

1.介绍 看这篇文章就好了 Vmware ESXi 是免费吗&#xff1f;一文弄懂vSphere功能特性及ESXi与vSphere到底有什么区别和联系。 - 知乎 (zhihu.com) 2.下载 这里面有7.0各个版本的下载镜像文件和校验信息 VMware-Esxi7.0各个版本镜像文件iso下载链接_esxi7.0镜像-CSDN博客 3.…

团结引擎+OpenHarmony 2 xlua编译篇

文章目录 前言一、下载 xlua 源码二、OpenHarmony SDK三、开干 前言 提示&#xff1a;我们的 app 鸿蒙化过程 需要用到 xlua ,目前没有适配 OpenHarmony 平台&#xff0c;所以需要重新编译一下。编译有多种方式&#xff0c;但是我只会这一种 就是使用 cmake。 一、下载 xlua 源…

花一分钟简单认识 CSS 中的规则 —— 级联层 @layer

layer 简介&#xff1a; 声明级联层时&#xff0c;越靠后优先级越高。不属于任何级联层的样式&#xff0c;将自成一层匿名级联层&#xff0c;并置于所有层之后 —— 级别最高。 用法一&#xff1a;在同一文件中 layer base, special; layer special {/* 优先 */li { color: …

2、Qt UI控件 -- qucsdk项目使用

前言&#xff1a;上一篇文章讲了qucsdk的环境部署&#xff0c;可以在QDesigner和Qt Creator中看到qucsdk控件&#xff0c;这一篇来讲下在项目中使用qucsdk库中的控件。 一、准备材料 要想使用第三方库&#xff0c;需要三个先决条件&#xff0c; 1、控件的头文件 2、动/静态链…

软考数据库---1.事务管理

目录 1.1 事物的基本概念1.2 数据库的并发控制1.2.1 事务调度概念1.2.2 并发操作带来的问题1.2.3 并发控制技术1.2.4 隔离级别&#xff1a; 1.3 数据库的备份和恢复1.3.1 故障种类1.3.2 备份方法1.3.3 日志文件1.3.4 恢复 1.1 事物的基本概念 ●概念&#xff1a;一个操作序列&…

AiChat是什么?

AIChat是一款功能强大的聚合AI大模型智能聊天助手&#xff0c;为用户提供自动化的客服和聊天机器人服务。无论是需要为企业提供更好的客户体验&#xff0c;还是为个人用户提供高效便捷的服务&#xff0c;AIChat都是最佳选择。本文将详细介绍AIChat的特点和优势。 Aichat简介&am…

学习R语言第二天

R语言可以做什么 1.数据分析 R语言如何使用 1. 请看我的操作方式 2. 如何获取当前路径 -- 获取当前路径 > getwd() [1] "E:/R/RWorkSpace/day01" -- 修改当前路径 > setwd(dir "E:/R") > getwd() [1] "E:/R" 3.查看当下数据值的信…

HCIP课后习题之一

1、路由协议用工作机制上分为那几种&#xff1f;分别是&#xff1f; A&#xff1a;两种。分别是静态路由和动态路由&#xff08;可分为IGP和EGP&#xff09; 2、IGP和EGP协议有哪些&#xff1f; A&#xff1a;IGP: RIP、OSPF、ISIS、EIGRP EGP: BGP 3、路由优先级的用途&…

机器人坐标系转换之从世界坐标系到局部坐标系

三角函数实现 下面是代码c和python实现&#xff1a; #include <iostream> #include <cmath>struct Point {double x;double y; };class RobotCoordinateTransform { private:Point origin; // 局部坐标系的原点在世界坐标系中的坐标public:RobotCoordinateTransfo…

zabbix企业级监控平台

zabbix部署 安装源 重新创建纯净环境&#xff0c;利用base克隆一台虚拟机server1 给server1做快照&#xff0c;方便下次实验恢复使用 进入zabbix官网https://www.zabbix.com rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm …

C++:构造函数、析构函数、拷贝构造函数

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《C&#xff1a;构造函数、析构函数、拷贝构造函数》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 如果本篇文章对你有帮助&#xff0c;还请各位点点赞…

c++的学习之路:16、list(3)

上章有一些东西当时没学到&#xff0c;这里学到了将在补充&#xff0c;文章末附上代码&#xff0c;思维导图。 目录 一、赋值重载 二、带模板的创建 三、析构函数 四、代码 五、思维导图 一、赋值重载 这里的赋值重载就是直接利用交换函数进行把传参生成的临时数据和需要…

Vue 读取后台二进制文件流转为图片显示

Vue 读取后台二进制文件流转为图片显示 后台返回格式 <img :src"payImg" id"image" style"width: 150px;height: 150px;" alt"">axios写法 重点 responseType: ‘blob’ &#xff0c; 使用的是res中的data blob this.$axios.…

Linux之线程互斥与同步

1.线程互斥相关概念 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源 。 临界区&#xff1a;每个线程内部&#xff0c;访问临界自娱的代码&#xff0c;就叫做临界区。 互斥&#xff1a;任何时刻&#xff0c;互斥保证有且只有一个执行流进入临界区&#xff0c;访问临…

【Locust分布式压力测试】

Locust分布式压力测试 https://docs.locust.io/en/stable/running-distributed.html Distributed load generation A single process running Locust can simulate a reasonably high throughput. For a simple test plan and small payloads it can make more than a thousan…