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

Qt实践:一个简单的丝滑侧滑栏实现

Qt实践:一个简单的丝滑侧滑栏实现

笔者前段时间突然看到了侧滑栏,觉得这个抽屉式的侧滑栏非常的有趣,打算这里首先尝试实现一个简单的丝滑侧滑栏。

首先是上效果图

(C,GIF帧率砍到毛都不剩了)

QPropertyAnimation

官方的QPropertyAnimation Class | Qt Core 6.8.1

也就是说,这个类封装了我们的Qt动画播放的类,我们针对Widgets的属性对其变化进行动画播放。Qt的抽象非常的好,只需要设置我们的起点和终点状态,以及设置一下时间间隔和播放的变化方式,就完事了。

  • setDuration(int msec): 设置动画的持续时间,单位是毫秒。

  • setStartValue(const QVariant &startValue): 设置动画的起始值。

  • setEndValue(const QVariant &endValue): 设置动画的结束值。

  • setEasingCurve(const QEasingCurve &curve): 设置动画的插值曲线,控制动画的速度变化(如加速、减速、匀速等)。常用的曲线类型有 QEasingCurve::LinearQEasingCurve::InQuadQEasingCurve::OutBounce 等。

笔者实现的效果的API就是用到了上面四个。

首先我们思考一下,SideBar看似是一个侧滑栏,但是跟随变动的,考虑上夹在中间的按钮,是三个部分。我们按照上面的思考思路。

1. 隐藏侧边栏(do_hide_animations

使侧边栏从可见状态过渡到隐藏状态。具体变化如下:

  • 侧边栏动画 (animation_side)

    • 起始状态:侧边栏的当前几何位置(ui->widgetSiderBar->geometry())。

    • 结束状态:侧边栏移动到视图外部,即其横坐标变为负值,具体位置为 ( - ui->widgetSiderBar->width(), ui->widgetSiderBar->y() )。这样侧边栏就被“隐藏”到屏幕外。

  • 按钮动画 (animation_button)

    • 起始状态:操作按钮当前的几何位置(ui->btn_operate->geometry())。

    • 结束状态:按钮的位置将移动到屏幕左侧,具体位置为 ( 0, ui->btn_operate->y() )。这样按钮会被移到左侧,表示侧边栏已隐藏。

  • 主界面动画 (animation_main)

    • 起始状态:主界面的当前几何位置(ui->widget_mainside->geometry())。

    • 结束状态:主界面位置根据按钮的位置进行调整,具体为 ( ui->btn_operate->width(), ui->widget_mainside->y() ),这意味着主界面会向左移动,避开被隐藏的侧边栏。

  • 操作按钮文本

    • 操作按钮的文本更改为 ">",表示点击后侧边栏会“展开”。

  • 执行动画:调用 group->start() 启动所有动画,产生隐藏效果。

2. 显示侧边栏(do_show_animations

当用户点击按钮以显示侧边栏时,执行 do_show_animations,将侧边栏从隐藏状态恢复到可见状态。具体变化如下:

  • 侧边栏动画 (animation_side)

    • 起始状态:侧边栏当前的几何位置(ui->widgetSiderBar->geometry())。

    • 结束状态:侧边栏移动到其原始位置,即横坐标变为 0,具体位置为 ( 0, ui->widgetSiderBar->y() ),使其重新显示在屏幕上。

  • 按钮动画 (animation_button)

    • 起始状态:操作按钮当前的几何位置(ui->btn_operate->geometry())。

    • 结束状态:按钮的位置将移动到侧边栏的右侧,具体为 ( ui->widgetSiderBar->width(), ui->btn_operate->y() ),表示按钮回到右侧,侧边栏已重新显示。

  • 主界面动画 (animation_main)

    • 起始状态:主界面的当前几何位置(ui->widget_mainside->geometry())。

    • 结束状态:主界面的位置调整为 ( ui->widgetSiderBar->width() + ui->btn_operate->width(), ui->widget_mainside->y() ),并且宽度变为 width() - ui->btn_operate->width() - ui->widgetSiderBar->width(),使得主界面重新适应显示的侧边栏。

  • 操作按钮文本

    • 操作按钮的文本更改为 "<",表示点击后侧边栏会“隐藏”。

  • 执行动画:调用 group->start() 启动所有动画,产生显示效果。

代码上的体现就是

void SideBarWidget::do_hide_animations() {animation_side->setStartValue(ui->widgetSiderBar->geometry());/* move to the hidden place */animation_side->setEndValue(QRect(-ui->widgetSiderBar->width(), ui->widgetSiderBar->y(),ui->widgetSiderBar->width(), ui->widgetSiderBar->height()));
​animation_button->setStartValue(ui->btn_operate->geometry());animation_button->setEndValue(QRect(0, ui->btn_operate->y(),ui->btn_operate->width(),ui->btn_operate->height()));
​animation_main->setStartValue(ui->widget_mainside->geometry());animation_main->setEndValue(QRect(ui->btn_operate->width(), ui->widget_mainside->y(),width() - ui->btn_operate->width(), ui->widget_mainside->height()));
​ui->btn_operate->setText(">");group->start();
}
void SideBarWidget::do_show_animations() {animation_side->setStartValue(ui->widgetSiderBar->geometry());/* move to the hidden place */animation_side->setEndValue(QRect(0, ui->widgetSiderBar->y(),ui->widgetSiderBar->width(),ui->widgetSiderBar->height()));
​animation_button->setStartValue(ui->btn_operate->geometry());animation_button->setEndValue(QRect(ui->widgetSiderBar->width(), ui->btn_operate->y(),ui->btn_operate->width(), ui->btn_operate->height()));
​animation_main->setStartValue(ui->widget_mainside->geometry());animation_main->setEndValue(QRect(ui->widgetSiderBar->width() + ui->btn_operate->width(),ui->widget_mainside->y(),width() - ui->btn_operate->width() - ui->widgetSiderBar->width(),ui->widget_mainside->height()));ui->btn_operate->setText("<");ui->widgetSiderBar->setVisible(true);group->start();
}
上面体现了一个优化,那就是使用动画组Group来同步的进行操作。防止出现动画抢跑。

源码

完整的测试源码在:CCQt_Libs/Widget/SideBarWidget at main · Charliechen114514/CCQt_Libs (github.com)

C++源码如下

#include "SideBarWidget.h"
#include "ui_SideBarWidget.h"
#include <QParallelAnimationGroup>
#include <QPropertyAnimation>namespace SideBarUtilsTools {
void clearLayout(QLayout* layout) {if (!layout) return;QLayoutItem* item;while ((item = layout->takeAt(0)) != nullptr) {if (item->widget()) {item->widget()->hide();  // 隐藏控件,但不删除} else {clearLayout(item->layout());  // 递归清理子布局}}
}
}  // namespace SideBarUtilsToolsSideBarWidget::SideBarWidget(QWidget* parent): QWidget(parent), ui(new Ui::SideBarWidget) {ui->setupUi(this);__initMemory();__initConnection();
}void SideBarWidget::switch_state() {setState(!hidden_state);
}void SideBarWidget::switch_button_visible() {setButtonVisible(!ui->btn_operate->isVisible());
}void SideBarWidget::removeLayout(Role r) {switch (r) {case Role::SideBar:SideBarUtilsTools::clearLayout(ui->widgetSiderBar->layout());break;case Role::MainSide:SideBarUtilsTools::clearLayout(ui->widget_mainside->layout());break;}
}void SideBarWidget::setButtonVisible(bool visible) {ui->btn_operate->setVisible(visible);ui->btn_operate->setText(hidden_state ? ">" : "<");
}void SideBarWidget::addLayout(QLayout* layout, const QWidgetList& widgetList,Role r) {switch (r) {case Role::SideBar:ui->widgetSiderBar->setLayout(layout);for (auto& w : widgetList) {ui->widgetSiderBar->layout()->addWidget(w);}break;case Role::MainSide:ui->widget_mainside->setLayout(layout);for (auto& w : widgetList) {ui->widget_mainside->layout()->addWidget(w);}break;}
}/* setTypes */
void SideBarWidget::setAnimationDuration(int duration) {animation_button->setDuration(duration);animation_main->setDuration(duration);animation_side->setDuration(duration);
}
void SideBarWidget::setAnimationCurve(QEasingCurve::Type curve) {animation_button->setEasingCurve(curve);animation_main->setEasingCurve(curve);animation_side->setEasingCurve(curve);
}void SideBarWidget::__initMemory() {animation_main = new QPropertyAnimation(ui->widget_mainside, "geometry");animation_main->setDuration(SideBarWidgetStaticConfig::ANIMATION_DURATION);animation_main->setEasingCurve(SideBarWidgetStaticConfig::ANIMATION_CURVE);animation_side = new QPropertyAnimation(ui->widgetSiderBar, "geometry");animation_side->setDuration(SideBarWidgetStaticConfig::ANIMATION_DURATION);animation_side->setEasingCurve(SideBarWidgetStaticConfig::ANIMATION_CURVE);animation_button = new QPropertyAnimation(ui->btn_operate, "geometry");animation_button->setDuration(SideBarWidgetStaticConfig::ANIMATION_DURATION);animation_main->setDuration(SideBarWidgetStaticConfig::ANIMATION_DURATION);group = new QParallelAnimationGroup(this);group->addAnimation(animation_main);group->addAnimation(animation_side);group->addAnimation(animation_button);
}void SideBarWidget::__initConnection() {connect(ui->btn_operate, &QPushButton::clicked, this,[this]() { setState(!hidden_state); });connect(group, &QParallelAnimationGroup::finished, this, [this] {ui->widgetSiderBar->setVisible(!hidden_state);// have no better idea :(, to update the layoutresize(size().width() + 1, size().height() + 1);resize(size().width() - 1, size().height() - 1);});
}void SideBarWidget::do_hide_animations() {animation_side->setStartValue(ui->widgetSiderBar->geometry());/* move to the hidden place */animation_side->setEndValue(QRect(-ui->widgetSiderBar->width(), ui->widgetSiderBar->y(),ui->widgetSiderBar->width(), ui->widgetSiderBar->height()));animation_button->setStartValue(ui->btn_operate->geometry());animation_button->setEndValue(QRect(0, ui->btn_operate->y(),ui->btn_operate->width(),ui->btn_operate->height()));animation_main->setStartValue(ui->widget_mainside->geometry());animation_main->setEndValue(QRect(ui->btn_operate->width(), ui->widget_mainside->y(),width() - ui->btn_operate->width(), ui->widget_mainside->height()));ui->btn_operate->setText(">");group->start();
}
void SideBarWidget::do_show_animations() {animation_side->setStartValue(ui->widgetSiderBar->geometry());/* move to the hidden place */animation_side->setEndValue(QRect(0, ui->widgetSiderBar->y(),ui->widgetSiderBar->width(),ui->widgetSiderBar->height()));animation_button->setStartValue(ui->btn_operate->geometry());animation_button->setEndValue(QRect(ui->widgetSiderBar->width(), ui->btn_operate->y(),ui->btn_operate->width(), ui->btn_operate->height()));animation_main->setStartValue(ui->widget_mainside->geometry());animation_main->setEndValue(QRect(ui->widgetSiderBar->width() + ui->btn_operate->width(),ui->widget_mainside->y(),width() - ui->btn_operate->width() - ui->widgetSiderBar->width(),ui->widget_mainside->height()));ui->btn_operate->setText("<");ui->widgetSiderBar->setVisible(true);group->start();
}SideBarWidget::~SideBarWidget() {delete ui;
}

接口文件如下:

#ifndef SIDEBARWIDGET_H
#define SIDEBARWIDGET_H#include <QEasingCurve>
#include <QWidget>
class QPropertyAnimation;
class QParallelAnimationGroup;
namespace SideBarWidgetStaticConfig {
static constexpr const bool               INIT_STATE         = false;
static constexpr const int                ANIMATION_DURATION = 500;
static constexpr const QEasingCurve::Type ANIMATION_CURVE =QEasingCurve::InOutQuad;
};  // namespace SideBarWidgetStaticConfignamespace Ui {
class SideBarWidget;
}class SideBarWidget : public QWidget {Q_OBJECTpublic:explicit SideBarWidget(QWidget* parent = nullptr);void inline showSideBar() {setState(false);}void inline hideSideBar() {setState(true);}enum class Role { SideBar, MainSide };/* addWidgets to the two sides */void addLayout(QLayout* layout, const QWidgetList& widgetList, Role r);/* remove the display widgets */void removeLayout(Role r);/* enable or disable the button visibilities */void setButtonVisible(bool visible);/* setTypes and durations */void setAnimationDuration(int duration);void setAnimationCurve(QEasingCurve::Type curve);~SideBarWidget();
public slots:void switch_state();void switch_button_visible();private:QPropertyAnimation*      animation_main;QPropertyAnimation*      animation_side;QPropertyAnimation*      animation_button;QParallelAnimationGroup* group;void inline setState(bool st) {hidden_state = st;hidden_state ? do_hide_animations() : do_show_animations();}void               __initMemory();void               __initConnection();void               do_hide_animations();void               do_show_animations();bool               hidden_state{SideBarWidgetStaticConfig::INIT_STATE};Ui::SideBarWidget* ui;
};#endif  // SIDEBARWIDGET_H

Reference

感谢https://zhuanlan.zhihu.com/p/614475116?utm_id=0,我的设计几乎从这里派生出来!

相关文章:

Qt实践:一个简单的丝滑侧滑栏实现

Qt实践&#xff1a;一个简单的丝滑侧滑栏实现 笔者前段时间突然看到了侧滑栏&#xff0c;觉得这个抽屉式的侧滑栏非常的有趣&#xff0c;打算这里首先尝试实现一个简单的丝滑侧滑栏。 首先是上效果图 &#xff08;C&#xff0c;GIF帧率砍到毛都不剩了&#xff09; QProperty…...

基于ESP32-IDF驱动GPIO输出控制LED

基于ESP32-IDF驱动GPIO输出控制LED 文章目录 基于ESP32-IDF驱动GPIO输出控制LED一、点亮LED3.1 LED电路3.2 配置GPIO函数gpio_config()原型和头文件3.3 设置GPIO引脚电平状态函数gpio_set_level()原型和头文件3.4 代码实现并编译烧录 一、点亮LED 3.1 LED电路 可以看到&#x…...

OpenCV文字绘制支持中文显示

OpenCV版本&#xff1a;4.4 IDE&#xff1a;VS2019 功能描述 OpenCV绘制文本的函数putText()不支持中文的显示&#xff0c;网上很多方法推荐的都是使用FreeType来支持&#xff0c;FreeType是什么呢&#xff1f;FreeType的官网上有介绍 FreeType官网 https://www.freetype.or…...

jenkins-k8s pod方式动态生成slave节点

一. 简述&#xff1a; 使用 Jenkins 和 Kubernetes (k8s) 动态生成 Slave 节点是一种高效且灵活的方式来管理 CI/CD 流水线。通过这种方式&#xff0c;Jenkins 可以根据需要在 Kubernetes 集群中创建和销毁 Pod 来执行任务&#xff0c;从而充分利用集群资源并实现更好的隔离性…...

消息队列篇--基础篇(消息队列特点,应用场景、点对点和发布订阅工作模式,RabbmitMQ和Kafka代码示例等)

1、消息队列的介绍 消息&#xff08;Message&#xff09;是指在应用之间传送的数据&#xff0c;消息可以非常简单&#xff0c;比如只包含文本字符串&#xff0c;也可以更复杂&#xff0c;可能包含嵌入对象。 消息队列&#xff08;Message Queue&#xff0c;简称MQ&#xff09…...

Jetpack架构组件学习——使用Glance实现桌面小组件

基本使用 1.添加依赖 添加Glance依赖: // For AppWidgets supportimplementation "androidx.glance:glance-appwidget:1.1.0"// For interop APIs with Material 3implementation "androidx.glance:glance-material3:1.1.0"// For interop APIs with Mater…...

go读取excel游戏配置

1.背景 游戏服务器&#xff0c;配置数据一般采用csv/excel来作为载体&#xff0c;这种方式&#xff0c;策划同学配置方便&#xff0c;服务器解析也方便。在jforgame框架里&#xff0c;我们使用以下的excel配置格式。 然后可以非常方便的进行数据检索&#xff0c;例如&#xff…...

Linux系统下速通stm32的clion开发环境配置

陆陆续续搞这个已经很久了。 因为自己新电脑是linux系统无法使用keil&#xff0c;一开始想使用vscode里的eide但感觉不太好用&#xff1b;后面想直接使用cudeide但又不想妥协&#xff0c;想趁着这个机会把linux上的其他单片机开发配置也搞明白&#xff1b;而且非常想搞懂cmake…...

快慢指针及原理证明(swift实现)

目录 链表快慢指针一、快慢指针基本介绍二、快慢指针之找特殊节点1.删除链表的倒数第k个结点题目描述解题思路 2.链表的中间节点题目描述解题思路 三、快慢指针之环形问题1.判断环形链表题目描述解题思路 2.判断环形链表并返回入环节点题目描述解题思路 3.变种——判断快乐数题…...

web前端3--css

注意&#xff08;本文一切代码一律是在vscode中书写&#xff09; 1、书写位置 1、行内样式 //<标签名 style"样式声明"> <p style"color: red;">666</p> 2、内嵌样式 1、style标签 里面写css代码 css与html之间分离 2、css属性:值…...

一文大白话讲清楚webpack基本使用——5——babel的配置和使用

文章目录 一文大白话讲清楚webpack基本使用——5——babel的配置和使用1. 建议按文章顺序从头看&#xff0c;一看到底&#xff0c;豁然开朗2. babel-loader的配置和使用2.1 针对ES6的babel-loader2.2 针对typescript的babel-loader2.3 babel配置文件 一文大白话讲清楚webpack基…...

Python自动化运维:一键掌控服务器的高效之道

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在互联网和云计算高速发展的今天,服务器数量的指数增长使得手动运维和管理变得异常繁琐。Python凭借其强大的可读性和丰富的生态系统,成为…...

基于quartz,刷新定时器的cron表达式

文章目录 前言基于quartz&#xff0c;刷新定时器的cron表达式1. 先看一下测试效果2. 实现代码 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&…...

HTML常用属性

HTML标签的常见属性包括许多不同的功能&#xff0c;可以为元素提供附加信息或控制元素的行为。以下是一些常见的属性及其解释&#xff1a; 1. src 描述&#xff1a;src&#xff08;source&#xff09;属性指定一个资源的路径&#xff0c;通常用于图像、音频、视频等标签。常见…...

在 Babylon.js 中使用 Gizmo:交互式 3D 操作工具

在 3D 应用程序中&#xff0c;交互式操作对象&#xff08;如平移、旋转、缩放&#xff09;是一个常见的需求。Babylon.js 提供了一个强大的工具——Gizmo&#xff0c;用于在 3D 场景中实现这些功能。本文将介绍如何在 Babylon.js 中使用 Gizmo&#xff0c;并展示如何通过代码实…...

蓝桥杯练习日常|递归-进制转换

蓝桥云课760数的计算 一、递归 题目&#xff1a; 我的解题代码&#xff1a; #include <iostream> using namespace std; int sum0; int main() {// 请在此输入您的代码int n;cin>>n;int fun(int n);fun(n); cout<<sum<<\n;return 0; } // void fu…...

LabVIEW滤波器选择与参数设置

在信号处理应用中&#xff0c;滤波器是去除噪声、提取目标信号的重要工具。LabVIEW 提供多种类型的滤波器&#xff08;如低通、高通、带通、带阻&#xff09;&#xff0c;用户需要根据采样频率、信号特性和应用需求合理选择滤波器类型及参数设置。本文以 采样率 100kHz&#xf…...

【c语言日寄】Vs调试——新手向

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…...

C#中的Timers.Timer使用用法及常见报错

System.Timers.Timer 是一个基于服务器的计时器&#xff0c;它可以在应用程序中定期触发事件。这个计时器特别适合用于多线程环境&#xff0c;并且不应该与用户界面(UI)直接交互。在 ASP.NET 中&#xff0c;通常使用 System.Timers.Timer 来处理周期性的任务。 主要使用步骤&am…...

chrome小插件:长图片等分切割

前置条件&#xff1a; 安装有chrome谷歌浏览器的电脑 使用步骤&#xff1a; 1.打开chrome扩展插件 2.点击管理扩展程序 3.加载已解压的扩展程序 4.选择对应文件夹 5.成功后会出现一个扩展小程序 6.点击对应小程序 7.选择图片进行切割&#xff0c;切割完成后会自动保存 代码…...

mysql数据被误删的恢复方案

文章目录 一、使用备份恢复二、使用二进制日志&#xff08;Binary Log&#xff09;三、使用InnoDB表空间恢复四、使用第三方工具预防措施 数据误删是一个严重的数据库管理问题&#xff0c;但通过合理的备份策略和使用适当的恢复工具&#xff0c;可以有效地减少数据丢失的风险…...

K8S-Pod资源清单的编写,资源的增删改查,镜像的下载策略

1. Pod资源清单的编写 1.1 Pod运行单个容器的资源清单 ##创建工作目录 mkdir -p /root/manifests/pods && cd /root/manifests/pods vim 01-nginx.yaml ##指定api版本 apiVersion: v1 ##指定资源类型 kind: Pod ##指定元数据 metadata:##指定名称name: myweb ##用户…...

Unity Line Renderer Component入门

Overview Line Renderer 组件是 Unity 中用于绘制连续线段的工具。它通过在三维空间中的两个或两个以上的点的数组&#xff0c;并在每个点之间绘制一条直线。可以绘制从简单的直线到复杂的螺旋线等各种图形。 1. 连续性和独立线条 连续性&#xff1a;Line Renderer 绘制的线条…...

计算机工程:解锁未来科技之门!

计算机工程与应用是一个充满无限可能性的领域。随着科技的迅猛发展&#xff0c;计算机技术已经深深渗透到我们生活的方方面面&#xff0c;从医疗、金融到教育&#xff0c;无一不在彰显着计算机工程的巨大魅力和潜力。 在医疗行业&#xff0c;计算机技术的应用尤为突出。比如&a…...

翻译:How do I reset my FPGA?

文章目录 背景翻译&#xff1a;How do I reset my FPGA?1、Understanding the flip-flop reset behavior2、Reset methodology3、Use appropriate resets to maximize utilization4、Many options5、About the author 背景 在写博客《复位信号的同步与释放&#xff08;同步复…...

在Unity中使用大模型进行离线语音识别

文章目录 1、Vosk下载下载vosk-untiy-asr下载模型在项目中使用语音转文字音频转文字2、whisper下载下载unity项目下载模型在unity中使用1、Vosk 下载 下载vosk-untiy-asr Github链接:https://github.com/alphacep/vosk-unity-asr 进不去Github的可以用网盘 夸克网盘链接:h…...

SpringBoot+Vue使用Echarts

前言 在vue项目中使用echarts&#xff0c;本次演示是使用vue2 1 前端准备 echarts官网&#xff1a; https://echarts.apache.org/zh/index.html 官网提供了基本的使用说明和大量的图表 1.1 下载echarts 执行命令 npm install echarts 直接这样执行很可能会失败&#xff0c;…...

【QT】-explicit关键字

explicit explicit 是一个 C 关键字&#xff0c;用于修饰构造函数。它的作用是防止构造函数进行隐式转换。 为什么需要 explicit&#xff1f; 在没有 explicit 的情况下&#xff0c;构造函数可以用于隐式类型转换。这意味着&#xff0c;如果你有一个接受某种类型的参数的构造…...

docker: Device or resource busy

(base) [rootbddx-vr-gpu-bcc2 /]#rm -rf /ssd1/docker/overlay2/8d96a51e3fb78e434fcf2b085e952adcc82bfe37485d427e1e017361a277326d/ rm: cannot remove ‘/ssd1/docker/overlay2/8d96a51e3fb78e434fcf2b085e952adcc82bfe37485d427e1e017361a277326d/merged’: Device or re…...

Vue - toRefs() 和 toRef() 的使用

一、toRefs() 在 Vue 3 中,toRefs()可以将响应式对象的属性转换为可响应的 refs。主要用于在解构响应式对象时&#xff0c;保持属性的响应性。 1. 导入 toRefs 函数 import { toRefs } from vue;2. 将响应式对象的属性转换为 ref const state reactive({count: 0,message:…...

(2024,MLLM,Healthcare,综述)多模态学习是否已在医疗保健领域实现通用智能?

Has Multimodal Learning Delivered Universal Intelligence in Healthcare? A Comprehensive Survey 目录 0. 摘要 1. 简介 5. MLLM 5.1 模态编码器与跨模态适配器 5.1.1 图像编码器 (Image Encoder) 5.1.2 语言模型 (Language Model) 5.1.3 跨模态适配器 (Cross-moda…...

css命名规范——BEM

目录 引言 BEM是什么? 块Block 元素Element 修饰语Modifier BEM解决了哪些问题? 在流行框架的组件中使用 BEM 格式 实战 认识设计图 如何使用当前的css规范正确命名? 引言 css样式类命名难、太难了,难于上青天,这个和js变量命名还不一样。看看项目中五花八门的样…...

使用PHP函数 “is_object“ 检查变量是否为对象类型

在PHP中&#xff0c;变量可以保存不同类型的值&#xff0c;包括整数、字符串、数组、布尔值等等。其中&#xff0c;对象是一种特殊的数据类型&#xff0c;用于封装数据和方法。在处理PHP代码中&#xff0c;我们经常需要检查一个变量是否为对象类型&#xff0c;以便进行相应的处…...

Golang:使用DuckDB查询Parquet文件数据

本文介绍DuckDB查询Parquet文件的典型应用场景&#xff0c;掌握DuckDB会让你的产品分析能力更强&#xff0c;相反系统运营成本相对较低。为了示例完整&#xff0c;我也提供了如何使用Python导出MongoDB数据。 Apache Parquet文件格式在存储和传输大型数据集方面变得非常流行。最…...

Moretl FileSync增量文件采集工具

永久免费: <下载> <使用说明> 我们希望Moretl FileSync是一款通用性很好的文件日志采集工具,解决工厂环境下,通过共享目录采集文件,SMB协议存在的安全性,兼容性的问题. 同时,我们发现工厂设备日志一般为增量,为方便MES,QMS等后端系统直接使用数据,我们推出了增量采…...

消息队列篇--原理篇--Pulsar(Namespace,BookKeeper,类似Kafka甚至更好的消息队列)

Apache Pulusar是一个分布式、多租户、高性能的发布/订阅&#xff08;Pub/Sub&#xff09;消息系统&#xff0c;最初由Yahoo开发并开源。它结合了Kafka和传统消息队列的优点&#xff0c;提供高吞吐量、低延迟、强一致性和可扩展的消息传递能力&#xff0c;适用于大规模分布式系…...

linux 扩容

tmpfs tmpfs 82M 0 82M 0% /run/user/1002 tmpfs tmpfs 82M 0 82M 0% /run/user/0 [输入命令]# fdisk -lu Disk /dev/vda: 40 GiB, 42949672960 bytes, 83886080 sectors Units: sectors of 1 * 512 512 bytes Sector size (logi…...

数据表中的数据查询

文章目录 一、概述二、简单查询1.列出表中所有字段2.“*”符号表示所有字段3.查询指定字段数据4.DISTINCT查询 三、IN查询四、BETWEEN ADN查询1.符合范围的数据记录查询2.不符合范围的数据记录查询 五、LIKE模糊查询六、对查询结果排序七、简单分组查询1.统计数量2.统计计算平均…...

深入了解 Java split() 方法:分割字符串的利器

Java 提供的 split() 方法是 String 类中一个常用的工具&#xff0c;它可以将一个字符串根据指定的分隔符切割成多个子字符串&#xff0c;并以字符串数组的形式返回。这个方法常用于字符串的处理、数据解析等场景。本文将详细介绍 Java 中 split() 方法的使用方式&#xff0c;并…...

Ubuntu 安装 docker 配置环境及其常用命令

Docker 安装与配置指南 本文介绍如何在 Ubuntu 系统上安装 Docker&#xff0c;解决权限问题&#xff0c;配置 Docker Compose&#xff0c;代理端口转发&#xff0c;容器内部代理问题等并进行相关的优化设置。参考官方文档&#xff1a;Docker 官方安装指南 一、安装 Docker 1…...

Android Studio安装配置

一、注意事项 想做安卓app和开发板通信&#xff0c;踩了大坑&#xff0c;Android 开发不是下载了就能直接开发的&#xff0c;对于新手需要注意的如下&#xff1a; 1、Android Studio版本&#xff0c;根据自己的Android Studio版本对应决定了你所兼容的AGP&#xff08;Android…...

leetcode 面试经典 150 题:有效的括号

链接有效的括号题序号20题型字符串解法栈难度简单熟练度✅✅✅ 题目 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须…...

C语言 指针_野指针 指针运算

野指针&#xff1a; 概念&#xff1a;野指针就是指针指向的位置是不可知的&#xff08;随机的、不正确的、没有明确限制的&#xff09; 指针非法访问&#xff1a; int main() {int* p;//p没有初始化&#xff0c;就意味着没有明确的指向//一个局部变量不初始化&#xff0c;放…...

【HarmonyOS之旅】基于ArkTS开发(二) -> UI开发之常见布局

目录 1 -> 自适应布局 1.1 -> 线性布局 1.1.1 -> 线性布局的排列 1.1.2 -> 自适应拉伸 1.1.3 -> 自适应缩放 1.1.4 -> 定位能力 1.1.5 -> 自适应延伸 1.2 -> 层叠布局 1.2.1 -> 对齐方式 1.2.2 -> Z序控制 1.3 -> 弹性布局 1.3.1…...

java基础学习——jdbc基础知识详细介绍

引言 数据的存储 我们在开发 java 程序时&#xff0c;数据都是存储在内存中的&#xff0c;属于临时存储&#xff0c;当程序停止或重启时&#xff0c;内存中的数据就会丢失&#xff0c;我们为了解决数据的长期存储问题&#xff0c;有以下解决方案&#xff1a; 通过 IO流书记&…...

第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组

第十五届的题目在规定时间内做出了前5道&#xff0c;还有2道找时间再磨一磨。现在把做的一些思路总结如下&#xff1a; 题1&#xff1a;握手问题 问题描述 小蓝组织了一场算法交流会议&#xff0c;总共有 50人参加了本次会议。在会议上&#xff0c;大家进行了握手交流。按照惯例…...

基于JAVA的微信点餐小程序设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

2K320Hz显示器哪个好?

2K320Hz显示器哪个好&#xff1f;320Hz这种高刷新率的显示器确实很少见&#xff0c;那究竟哪个牌子哪个型号更适合你呢&#xff1f; 1.HKC G27H4Pro - 2K320Hz显示器哪个好 外观设计 - HKC G27H4Pro 2K320Hz显示器 三面微边框超震撼&#xff1a;采用三面微边框设计&#xff0…...

八股学习 微服务篇

微服务篇 常见面试内容Spring Cloud 常见组件注册中心Ribbon负载均衡策略服务雪崩 常见面试内容 Spring Cloud 常见组件 Spring Cloud有5个常见组件&#xff1a; Eureka/Nacos:注册中心&#xff1b;Ribbon:负载均衡&#xff1b;Feign:远程调用&#xff1b;Hystrix/Sentinel:服…...

C# 中 readonly 与 const 的使用

总目录 前言 在C#编程中&#xff0c;readonly 和 const 是两个用于定义不可变数据的关键字。它们都旨在创建那些一旦赋值后就不能再改变的字段或变量。尽管这两个关键字看起来相似&#xff0c;但它们有着不同的特性和适用场景。本文将深入探讨 readonly 和 const 的区别&#…...