Qt实现一个悬浮工具箱源码分享

news2025/6/7 13:36:13

一、效果展示

在这里插入图片描述

二、源码分享

hoverToolboxWidget.h

#ifndef HOVERTOOLBOXWIDGET_H
#define HOVERTOOLBOXWIDGET_H

#include <QWidget>
#include <QMouseEvent>
#include <QPropertyAnimation>
#include <QStyleOption>
#include <QPainter>

namespace Ui {
class HoverToolboxWidget;
}

class HoverToolboxWidget : public QWidget
{
    Q_OBJECT
signals:
    void btnClickSlot(QString fun);
public:
    explicit HoverToolboxWidget(QWidget *parent = nullptr);
    ~HoverToolboxWidget();
protected:
    void paintEvent(QPaintEvent *event) override;
    bool eventFilter(QObject *obj,QEvent *event) override;
private:
    void controlInit();
    void extand();
private:
    Ui::HoverToolboxWidget *ui;
    bool isDragging = false,isExtending = false;
    QPointF dragPos;
    QPropertyAnimation *amplifyAnimation,*leaveAnimation;
    static const uint8_t cellSize = 75;
};

#endif // HOVERTOOLBOXWIDGET_H

hoverToolboxWidget.cpp

#include "hoverToolboxWidget.h"
#include "ui_hoverToolboxWidget.h"

HoverToolboxWidget::HoverToolboxWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::HoverToolboxWidget)
{
    ui->setupUi(this);
    this->controlInit();
}

HoverToolboxWidget::~HoverToolboxWidget()
{
    delete ui;
}
void HoverToolboxWidget::controlInit()
{
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    setAttribute(Qt::WA_TranslucentBackground, true);

    this->ui->labelImage->installEventFilter(this);
    this->ui->labelImage->setMouseTracking(true);

    this->ui->frame->installEventFilter(this);
    this->ui->frame->setMouseTracking(true);

    this->ui->pushButton1->hide();
    this->ui->pushButton2->hide();
    this->ui->pushButton3->hide();
    this->ui->pushButton4->hide();
    this->ui->pushButton5->hide();
    this->ui->pushButton6->hide();
    this->ui->pushButton7->hide();
    this->ui->pushButton8->hide();
    this->resize(cellSize,cellSize);

    this->setAttribute(Qt::WA_StyledBackground, true);

    connect(this->ui->pushButton1,&QPushButton::clicked,this,
            [=]()
            {
                emit btnClickSlot("openRootDir");
            });
    connect(this->ui->pushButton1,&QPushButton::clicked,this,
            [=]()
            {
                emit btnClickSlot("screenShot");
            });
}

void HoverToolboxWidget::extand()
{
    if(!isExtending)
    {
        auto pos = this->pos();

        int x = pos.x()-cellSize-this->ui->frame->layout()->spacing();
        int y = pos.y()-cellSize-this->ui->frame->layout()->spacing();

        int wh = cellSize*3 + this->ui->frame->layout()->spacing()*2 + this->ui->labelImage->pos().x()*2;

        this->setGeometry(x,y,wh,wh);
        this->ui->pushButton1->show();
        this->ui->pushButton2->show();
        this->ui->pushButton3->show();
        this->ui->pushButton4->show();
        this->ui->pushButton5->show();
        this->ui->pushButton6->show();
        this->ui->pushButton7->show();
        this->ui->pushButton8->show();

        //判断有没有超出边界
        int jx = this->pos().x();
        int jy = this->pos().y();

        if(jx < 0)
            jx = 0;
        if(jx+this->width() > this->parentWidget()->width())
            jx = this->parentWidget()->width()-this->width();

        if(jy < 0)
            jy = 0;
        if(jy + this->height() > this->parentWidget()->height())
            jy = this->parentWidget()->height() - this->height();


        this->move(jx,jy);
        isExtending = true;

        this->ui->labelImage->setPixmap(QPixmap(":/image/image/toolboxOpen.svg"));
    }
}

void HoverToolboxWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QStyleOption option;
    option.initFrom(this);
    QPainter painter(this);
    style()->drawPrimitive(QStyle::PE_Widget, &option, &painter, this);
}


bool HoverToolboxWidget::eventFilter(QObject *obj, QEvent *event)
{
    if(obj == this->ui->labelImage)
    {
        if(event->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent *ev = dynamic_cast<QMouseEvent *>(event);
            if (ev->button() == Qt::LeftButton)
            {
                isDragging = true;
                dragPos = ev->globalPosition() - frameGeometry().topLeft();
            }
            if (ev->button() == Qt::RightButton)
            {
                this->extand();
            }
        }
        else if(event->type() == QEvent::MouseMove)
        {
            QMouseEvent *ev = dynamic_cast<QMouseEvent *>(event);
            if (isDragging)
            {
                QPointF movePoint = ev->globalPosition() - dragPos;
                int x = movePoint.x();
                int y = movePoint.y();
                if(x < 0)
                    x = 0;
                if((x+this->width()) > this->parentWidget()->width())
                    x = this->parentWidget()->width() - this->width();

                if(y < 0)
                    y = 0;
                if((y+this->height()) > this->parentWidget()->height())
                    y = this->parentWidget()->height() - this->height();

                this->move(x,y);
            }
        }
        else if(event->type() == QEvent::MouseButtonRelease)
        {
            QMouseEvent *ev = dynamic_cast<QMouseEvent *>(event);
            if (ev->button() == Qt::LeftButton) {
                isDragging = false;
            }
        }
        else if(event->type() == QEvent::MouseButtonDblClick)
        {
            this->extand();
        }
    }
    else if(obj == this->ui->frame)
    {
        if(event->type() == QEvent::Leave)
        {
            if(isExtending)
            {
                isExtending = false;
                auto pos = this->pos();

                this->ui->pushButton1->hide();
                this->ui->pushButton2->hide();
                this->ui->pushButton3->hide();
                this->ui->pushButton4->hide();
                this->ui->pushButton5->hide();
                this->ui->pushButton6->hide();
                this->ui->pushButton7->hide();
                this->ui->pushButton8->hide();

                int x = pos.x()+cellSize + this->ui->frame->layout()->spacing();
                int y = pos.y()+cellSize + this->ui->frame->layout()->spacing();

                this->setGeometry(x,y,cellSize,cellSize);

                this->ui->labelImage->setPixmap(QPixmap(":/image/image/toolboxClose.svg"));
            }
        }
    }

    return QWidget::eventFilter(obj,event);
}

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

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

相关文章

线夹金具测温在线监测装置:电力设备安全运行的“隐形卫士”

在电网系统中&#xff0c;线夹金具是连接导线与输电塔架的关键部件&#xff0c;其运行状态直接影响电力传输的稳定性。传统人工巡检方式存在效率低、盲区多、数据滞后等问题&#xff0c;而线夹金具测温在线监测装置的普及&#xff0c;正为电力设备运维带来革新。 一、工作原理&…

《TCP/IP 详解 卷1:协议》第4章:地址解析协议

ARP 协议 地址解析协议&#xff08;ARP, Address Resolution Protocol&#xff09;是IPv4协议栈中一个关键的组成部分&#xff0c;用于在网络层的IP地址与数据链路层的硬件地址&#xff08;如MAC地址&#xff09;之间建立映射关系。它的主要任务是&#xff1a; 将32位的IPv4地…

Windows下运行Redis并设置为开机自启的服务

下载Redis-Windows 点击redis-windows-7.4.0下载链接下载Redis 解压之后得到如下文件 右键install_redis.cmd文件&#xff0c;选择在记事本中编辑。 将这里改为redis.windows.conf后保存&#xff0c;退出记事本&#xff0c;右键后选择以管理员身份运行。 在任务管理器中能够…

网络编程之网络基础

基础理论&#xff1a;IP、子网掩码、端口号、字节序、网络基础模型、传输协议 socket&#xff1a;TCP、UDP、广播、组播、抓包工具的使用、协议头、并发服务器 Modbus协议 、HTTP协议、HTML、 分析服务器 源码、数据库 一、认识网络 网络&#xff1a;实现多设备通信 二、IP地址…

Spring AI(11)——SSE传输的MCP服务端

WebMVC的服务器传输 支持SSE&#xff08;Server-Sent Events&#xff09; 基于 Spring MVC 的服务器传输和可选的STDIO运输 导入jar <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webmvc</a…

计算机网络备忘录

计算机网络 - 网络互联与互联网 计算机网络重点学习本章&#xff0c;属于核心知识 包含网络层和传输层 的 相关协议 计算机网络层次重点掌握网络层与传输层。其中网络层主要是IP协议&#xff0c;解决主机-主机通信&#xff0c;传输层主要是TCP/UDP 协议&#xff0c;解决应用-…

Spring Boot论文翻译防丢失 From船长cap

本文内容 微服务 微服务风格的特性组件化&#xff08;Componentization &#xff09;与服务&#xff08;Services&#xff09;围绕业务功能的组织产品不是项目强化终端及弱化通道分散治理分散数据管理基础设施自动化容错性设计设计改进 微服务是未来吗其它 微服务系统多大微…

NuxtJS入门指南:环境安装及报错解决

在学习NuxtJS的过程中&#xff0c;正确的安装环境是非常重要的一步。然而&#xff0c;有时候在安装过程中会遇到一些问题&#xff0c;比如使用corepack安装pnpm时出现的错误。本文将详细介绍如何安装NuxtJS以及解决上述安装过程中遇到的问题。 Nuxt.js简介 Nuxt.js是一个强大的…

贪心算法应用:集合划分问题详解

贪心算法与集合划分问题详解 集合划分问题是组合优化中的经典问题&#xff0c;其核心目标是将元素集合划分为若干满足特定条件的子集。本文将深入探讨贪心算法在集合划分中的应用&#xff0c;涵盖算法原理、适用场景、Java实现细节及优化策略。 一、集合划分问题定义 1.1 基础…

数论~~~

质数 质数Miller-Rabin算法质因子分解质数筛埃氏筛欧拉筛如果只是计数&#xff0c;埃氏筛改进 快速幂乘法快速幂矩阵快速幂1维k阶实战(提醒&#xff1a;最好在mul函数中作乘法时加上&#xff08;long long&#xff09;的强制类型转换 &#xff0c;或者全部数组换成long long&am…

web第十次课后作业--Mybatis的增删改查

&#xff08;一&#xff09;删除操作 功能&#xff1a;根据主键删除数据 SQL 语句 -- 删除id17的数据 delete from emp where id 17;Mybatis 框架让程序员更关注于 SQL 语句 接口方法 Mapper public interface EmpMapper {//Delete("delete from emp where id 17&qu…

贪心算法应用:集合覆盖问题详解

贪心算法与集合覆盖问题详解 贪心算法在组合优化问题中展现出独特优势&#xff0c;集合覆盖问题&#xff08;Set Cover Problem&#xff09;是其中的经典案例。本文将用2万字全面解析贪心算法在集合覆盖/划分中的应用&#xff0c;涵盖算法原理、正确性分析、Java实现、复杂度证…

【知识点】第7章:文件和数据格式化

文章目录 知识点整理文件概述文件的打开和关闭文件的读操作文件的写操作 练习题填空题选择题​​ 知识点整理 文件概述 文件是一个存储在辅助存储器上的数据序列&#xff0c;可以包含任何数据内容。概念上&#xff0c;文件是数据的集合和抽象&#xff0c;类似地&#xff0c;函…

NetSuite Bundle - Dashboard Refresh

儿童节快乐&#xff01; 今朝发一个Bundle&#xff0c;解决一个NetSuite Dashboard的老问题。出于性能上的考虑&#xff0c;NetSuite的Dashboard中的Portlet&#xff0c;只能逐一手工刷新。有人基于浏览器做了插件&#xff0c;可以进行自动刷新。但是在我们做项目部署时&#…

智慧赋能:移动充电桩的能源供给革命与便捷服务升级

在城市化进程加速与新能源汽车普及的双重推动下&#xff0c;移动充电桩正成为能源供给领域的一场革命。传统固定充电设施受限于布局与效率&#xff0c;难以满足用户即时、灵活的充电需求&#xff0c;而移动充电桩通过技术创新与服务升级&#xff0c;打破了时空壁垒&#xff0c;…

斐波那契数列------矩阵幂法

斐波那契数列 斐波拉楔数是我们在学递归的使用看到的题目&#xff0c;但递归法是比较慢的&#xff0c;后面我们用循环递进来写的&#xff0c;但今天我有遇到了新的方法—— 矩阵幂法&#xff08;线性代数的知识点&#xff09;。 矩阵幂法&#xff1a; F11*F10*F2; F20*F11*…

【Web应用】若依框架:基础篇21二次开发-页面调整

文章目录 ⭐前言⭐一、课程讲解⭐二、怎样选择设计模式&#xff1f;&#x1f31f;1、寻找合适的对象✨1) ⭐三、怎样使用设计模式&#xff1f;&#x1f31f;1、寻找合适的对象✨1) ⭐总结 标题详情作者JosieBook头衔CSDN博客专家资格、阿里云社区专家博主、软件设计工程师博客内…

【 java 基础知识 第一篇 】

目录 1.概念 1.1.java的特定有哪些&#xff1f; 1.2.java有哪些优势哪些劣势&#xff1f; 1.3.java为什么可以跨平台&#xff1f; 1.4JVM,JDK,JRE它们有什么区别&#xff1f; 1.5.编译型语言与解释型语言的区别&#xff1f; 2.数据类型 2.1.long与int类型可以互转吗&…

CVE-2020-17518源码分析与漏洞复现(Flink 路径遍历)

漏洞概述 漏洞名称&#xff1a;Apache Flink REST API 任意文件上传漏洞 漏洞编号&#xff1a;CVE-2020-17518 CVSS 评分&#xff1a;7.5 影响版本&#xff1a;Apache Flink 1.5.1 - 1.11.2 修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0 漏洞类型&#xff1a;路径遍历导致的任…

Excel表格批量下载 CyberWin Excel Doenlaoder 智能编程-——玄武芯辰

使用 CyberWin Excel Downloader 进行 Excel 表格及各种文档的批量下载&#xff0c;优势显著。它能大幅节省时间&#xff0c;一次性获取大量所需文档&#xff0c;无需逐个手动下载&#xff0c;提升工作效率。可确保数据完整性与准确性&#xff0c;避免因重复操作产生失误。还便…