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

Qt自定义标题栏

效果如下:
在这里插入图片描述
代码如下:

// widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
protected:bool nativeEvent(const QByteArray&eventType,void *message,long*result) override;
private slots:void on_close();private:void mousePressEvent(QMouseEvent*ev);void mouseMoveEvent(QMouseEvent*ev);QPoint pos;
private:Ui::Widget *ui;int m_BorderWidth  =5;
};//2、titlebar
#ifndef CTABTITLEWIDGET_H
#define CTABTITLEWIDGET_H#include <QObject>
#include <QWidget>
#include<QPushButton>class CTabTitleWidget : public QWidget
{Q_OBJECT
public:explicit CTabTitleWidget(QWidget *parent = nullptr);~CTabTitleWidget();void setEmptyWidgetWidth(int w);protected:void paintEvent(QPaintEvent*event);void mousePressEvent(QMouseEvent*ev);void mouseDoubleClickEvent(QMouseEvent*event);signals:void sig_close();void sig_addtab();
private slots:void on_clicked();private:QPushButton* m_pAddBtn = nullptr;QWidget*     m_pEmptyWidget = nullptr;QPushButton* m_pUserBtn = nullptr;QPushButton* m_pMinBtn = nullptr;QPushButton* m_pMaxBtn = nullptr;QPushButton* m_pCloseBtn = nullptr;
};#endif // CTABTITLEWIDGET_H#endif // WIDGET_H//3.tabbrowser
#ifndef TABBROWSER_H
#define TABBROWSER_H#include <QObject>
#include <QWidget>
#include <QTabWidget>
#include <QMenu>
#include "ctabtitlewidget.h"
class tabbrowser : public QTabWidget
{Q_OBJECT
public:explicit tabbrowser(QWidget *parent = nullptr);enum TAB_FLAG{NEW,CLOSE,NORMAL,SPECIAL};protected:void resizeEvent(QResizeEvent*ev) override;private:void initTabWidget();void setTabBarFlag(TAB_FLAG);void createTabMenu();private slots:void on_newTab();void on_closeTab(int index);void onMenuShow(const QPoint&pos);void on_closeAllTab();private:CTabTitleWidget*m_pRightWidget = nullptr;QMenu* m_pTabMenu = nullptr;
signals:void sig_close();};#endif // TABBROWSER_H
.cpp
/./1.widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "tabbrowser.h"
#ifdef Q_OS_WIN
#include <qt_windows.h>
#include <Windows.h>
#include <windowsx.h>
#include <QHBoxLayout>
#include <QMouseEvent>
#endifWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 设置窗口为无边框setWindowFlag(Qt::FramelessWindowHint);setStyleSheet("background-color:#E3E4E7;");// 创建一个新的 tabbrowser 实例,并将其设置为此窗口的小部件tabbrowser* pTab = new tabbrowser(this);// 创建一个水平布局,并将 tabbrowser 添加到布局中QHBoxLayout* pHLay = new QHBoxLayout(this);pHLay->addWidget(pTab);pHLay->setContentsMargins(6, 6, 6, 6);setLayout(pHLay);// 连接 tabbrowser 的关闭信号到此窗口的 on_close 槽函数connect(pTab, &tabbrowser::sig_close, this, &Widget::on_close);
}Widget::~Widget()
{delete ui;
}// 处理自定义窗口行为的原生事件(例如,调整大小和移动)
bool Widget::nativeEvent(const QByteArray &eventType, void *message, long *result)
{Q_UNUSED(eventType)MSG* param = static_cast<MSG*>(message);switch (param->message){case WM_NCHITTEST:{int nX = GET_X_LPARAM(param->lParam) - this->geometry().x();int nY = GET_Y_LPARAM(param->lParam) - this->geometry().y();// 如果鼠标位于子控件上,则忽略此事件if (childAt(nX, nY) != nullptr)return QWidget::nativeEvent(eventType, message, result);// 当鼠标靠近边框时,进行调整大小操作if ((nX > 0) && (nX < m_BorderWidth))*result = HTLEFT;if ((nX > this->width() - m_BorderWidth) && (nX < this->width()))*result = HTRIGHT;if ((nY > 0) && (nY < m_BorderWidth))*result = HTTOP;if ((nY > this->height() - m_BorderWidth) && (nY < this->height()))*result = HTBOTTOM;if ((nX > 0) && (nX < m_BorderWidth) && (nY > 0) && (nY < m_BorderWidth))*result = HTTOPLEFT;if ((nX > this->width() - m_BorderWidth) && (nX < this->width()) && (nY > 0) && (nY < m_BorderWidth))*result = HTTOPRIGHT;if ((nX > 0) && (nX < m_BorderWidth) && (nY > this->height() - m_BorderWidth) && (nY < this->height()))*result = HTBOTTOMLEFT;if ((nX > this->width() - m_BorderWidth) && (nX < this->width()) && (nY > this->height() - m_BorderWidth) && (nY < this->height()))*result = HTBOTTOMRIGHT;return true;}}return QWidget::nativeEvent(eventType, message, result);
}// 处理关闭信号的槽函数
void Widget::on_close()
{close();
}// 处理鼠标按下事件以移动窗口
void Widget::mousePressEvent(QMouseEvent *ev)
{if (Qt::LeftButton == ev->button()){// 计算鼠标相对于窗口左上角的位置pos = ev->globalPos() - frameGeometry().topLeft();ev->accept();}
}// 处理鼠标移动事件以移动窗口
void Widget::mouseMoveEvent(QMouseEvent *ev)
{if (Qt::LeftButton & ev->buttons()){// 移动窗口到鼠标移动后的位置move(ev->globalPos() - pos);ev->accept();}
}

//2.titlebar
#include “CTabTitleWidget.h”

#include
#include
#include
#include

#ifdef Q_OS_WIN
#include <qt_windows.h>
#pragma comment(lib, “user32.lib”)
#endif
CTabTitleWidget::CTabTitleWidget(QWidget *parent)
: QWidget{parent}
{
setStyleSheet(“background-color:#E3E4E7”);
m_pAddBtn = new QPushButton(this);
m_pAddBtn->setFlat(true);
m_pAddBtn->setFixedSize(32, 32);
m_pAddBtn->setStyleSheet(“background-image:url(:/resources/add.svg)”);

m_pEmptyWidget = new QWidget(this);m_pUserBtn = new QPushButton(this);
m_pUserBtn->setFlat(true);
m_pUserBtn->setFixedSize(32, 32);
m_pUserBtn->setStyleSheet("background-image:url(:/resources/user)");m_pMinBtn = new QPushButton(this);
m_pMinBtn->setFlat(true);
m_pMinBtn->setFixedSize(32, 32);
m_pMinBtn->setStyleSheet("background-image:url(:/resources/min.svg)");m_pMaxBtn = new QPushButton(this);
m_pMaxBtn->setFlat(true);
m_pMaxBtn->setFixedSize(32, 32);
m_pMaxBtn->setStyleSheet("background-image:url(:/resources/max.svg)");m_pCloseBtn = new QPushButton(this);
m_pCloseBtn->setFlat(true);
m_pCloseBtn->setFixedSize(32, 32);
m_pCloseBtn->setStyleSheet("background-image:url(:/resources/close.svg)");QHBoxLayout* pHLay = new QHBoxLayout(this);
pHLay->addWidget(m_pAddBtn);
pHLay->addWidget(m_pEmptyWidget);
this->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
pHLay->addWidget(m_pUserBtn);
pHLay->addSpacing(8);
pHLay->addWidget(m_pMinBtn);
pHLay->addWidget(m_pMaxBtn);
pHLay->addWidget(m_pCloseBtn);
pHLay->setContentsMargins(1, 0, 1, 3);
setLayout(pHLay);connect(m_pAddBtn, &QPushButton::clicked, this, &CTabTitleWidget::on_clicked);
connect(m_pMinBtn, &QPushButton::clicked, this, &CTabTitleWidget::on_clicked);
connect(m_pMaxBtn, &QPushButton::clicked, this, &CTabTitleWidget::on_clicked);
connect(m_pCloseBtn, &QPushButton::clicked, this, &CTabTitleWidget::on_clicked);

}

CTabTitleWidget::~CTabTitleWidget()
{

}

void CTabTitleWidget::setEmptyWidgetWidth(int w)
{
m_pEmptyWidget->setMinimumWidth(w);
}

void CTabTitleWidget::paintEvent(QPaintEvent *event)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
QWidget::paintEvent(event);
}

void CTabTitleWidget::mousePressEvent(QMouseEvent ev)
{
if(ReleaseCapture())
{
QWidget
win = this->window();
if(win->isTopLevel())
{
SendMessage(HWND(win->winId()),WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0);
}
}
ev->ignore();
}

void CTabTitleWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
emit m_pMaxBtn->clicked();
}

void CTabTitleWidget::on_clicked()
{
QPushButtonbtn = qobject_cast<QPushButton>(sender());
QWidget*win = this->window();
if(win->isTopLevel())
{
if (btn == m_pAddBtn)
{
emit sig_addtab();
}
else if (btn == m_pMinBtn)
{
win->showMinimized();
}
else if (btn == m_pMaxBtn)
{
win->isMaximized() ? win->showNormal() : win->showMaximized();
}
else if (btn == m_pCloseBtn)
{
emit sig_close();
}
}
}
//3.tabbrowser
#include “tabbrowser.h”
#include
#include
#include
#include
#include

QString qss0 = “QTabBar::tab{
font: 75 12pt Arial;
text-align:left;
width:184px;
height:32;
background:#FFFFFF;
border:2px solid #FFFFFF;
border-bottom-color:#FFFFFF;
border-top-left-radius:4px;
border-top-right-radius:4px;
padding:2px;
margin-top:0px;
margin-right:1px;
margin-left:1px;
margin-bottom:0px;}
QTabBar::tab:selected{
color:#333333; /文字颜色/
background-color:#FFFFFF;}
QTabBar::tab:!selected{
color:#B2B2B2;
border-color:#FFFFFF;}
QTabBar::scroller{width: 0px;}”;

QString qss1 = "QTabBar::tab{ \
font: 75 12pt Arial; \
text-align:left; \
width:184px; \
height:32; \
background:#FFFFFF; \
border:2px solid #FFFFFF; \
border-bottom-color:#FFFFFF; \
border-top-left-radius:4px; \
border-top-right-radius:4px; \
padding:2px; \
margin-top:0px; \
margin-right:1px; \
margin-left:1px;  \
margin-bottom:0px;} \
QTabBar::tab:selected{  \color:#333333; /*文字颜色*/  \background-color:#FFFFFF;} \
QTabBar::tab:!selected{ \color:#B2B2B2; \border-color:#FFFFFF;} \
QTabBar::scroller{width: 36px;}";
tabbrowser::tabbrowser(QWidget *parent)
QTabWidget{parent}
{
this->addTab(new QWidget,u8"稻壳");
this->setUsesScrollButtons(true);//滚动鼠标可切换tab
this->setTabsClosable(true); //显示tab右侧的关闭按钮
this->setMovable(true);//设置可移动位置
initTabWidget();
setTabBarFlag(NORMAL);this->setStyleSheet(qss0);connect(this, &QTabWidget::tabCloseRequested,this, &tabbrowser::on_closeTab);

}

void tabbrowser::resizeEvent(QResizeEvent *ev)
{
setTabBarFlag(NORMAL);
QTabWidget::resizeEvent(ev);
}

void tabbrowser::initTabWidget()
{
this->setContextMenuPolicy(Qt::CustomContextMenu);
connect(this,&QTabWidget::customContextMenuRequested,this,&tabbrowser::onMenuShow);
createTabMenu();

m_pRightWidget = new CTabTitleWidget(this);this->setCornerWidget(m_pRightWidget, Qt::TopRightCorner);
connect(m_pRightWidget, &CTabTitleWidget::sig_addtab, this, &tabbrowser::on_newTab);
connect(m_pRightWidget, &CTabTitleWidget::sig_close, this, &tabbrowser::sig_close);

}

void tabbrowser::setTabBarFlag(TAB_FLAG flag)
{
int w = this->width();

int tabsWidth = 0;  //所有tab的总宽度
int tabsHeight = tabBar()->height();
int tabs = this->count();if (flag == NEW || flag == NORMAL)
{for (int i = 0; i < tabs; ++i){tabsWidth += tabBar()->tabRect(i).width();}
}
else
{for (int i = 0;i < tabs - 1;++i){tabsWidth += tabBar()->tabRect(i).width();}
}if (w > tabsWidth)
{m_pRightWidget->setEmptyWidgetWidth(w - tabsWidth - 32 * 5 - 15);this->setStyleSheet(qss0);
}
else
{//当所有tab的宽度大于整个tabWidget的宽时m_pRightWidget->setEmptyWidgetWidth(150);this->setStyleSheet(qss1);
}

}

void tabbrowser::createTabMenu()
{
m_pTabMenu = new QMenu(this);

QAction* pAcSave = new QAction(QIcon(":/resources/save.png"), u8"保存", m_pTabMenu);
m_pTabMenu->addAction(pAcSave);connect(pAcSave, &QAction::triggered, [=] {QMessageBox::information(this, u8"提示", u8"你点击了 保存");});QAction* pAcSaveAs = new QAction(QString(u8"另存为"), m_pTabMenu);
m_pTabMenu->addAction(pAcSaveAs);m_pTabMenu->addSeparator();QAction* pAcShareDoc = new QAction(QIcon(":/resources/share.png"), QString(u8"分享文档"), m_pTabMenu);
m_pTabMenu->addAction(pAcShareDoc);QAction* pAcSendToDevice = new QAction(QString(u8"发送到设备"), m_pTabMenu);
m_pTabMenu->addAction(pAcSendToDevice);m_pTabMenu->addSeparator();QAction* pAcNewName = new QAction(QString(u8"重命名"), m_pTabMenu);
m_pTabMenu->addAction(pAcNewName);QAction* pAcSaveToWPSCloud = new QAction(QString(u8"保存到WPS云文档"), m_pTabMenu);
m_pTabMenu->addAction(pAcSaveToWPSCloud);QAction* pAcCloseAll = new QAction(QString(u8"关闭所有文件"), m_pTabMenu);
m_pTabMenu->addAction(pAcCloseAll);
connect(pAcCloseAll, &QAction::triggered, this, &tabbrowser::on_closeAllTab);

}

void tabbrowser::on_newTab()
{
int nCount = count();
QString title = QString::number(nCount);
title = “Page” + title;

// 这里写的有问题,应该是 insertTab
this->addTab(new QWidget, title);if (!tabsClosable())
{setTabsClosable(true);
}setTabBarFlag(NEW);

}

void tabbrowser::on_closeTab(int index)
{
widget(index)->deleteLater();
setTabBarFlag(CLOSE);

//当只剩下1个tab时
if (count() == 1)
{setTabsClosable(false);setTabBarFlag(SPECIAL);
}

}

void tabbrowser::onMenuShow(const QPoint &pos)
{
int index = this->tabBar()->tabAt(pos);

#ifdef _DEBUG
qDebug() << u8"当前tab为:" << QString::number(index);
this->setCurrentIndex(index);
#endif

if (index != -1)
{m_pTabMenu->exec(QCursor::pos());
}

}

void tabbrowser::on_closeAllTab()
{

}

相关文章:

Qt自定义标题栏

效果如下&#xff1a; 代码如下&#xff1a; // widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr…...

java如何向数组中插入元素

java的数组是不可改变的&#xff0c;因此如果要向数组中插入新的元素&#xff0c;需要新建一个数组&#xff0c;新的数组元素个数减去老数组元素个数的差大于等于要插入新的元素数量。 假如说要插入一个数组元素&#xff0c;需要把新元素插入到中间&#xff0c;把新的数组分为…...

4、PHP的xml注入漏洞(xxe)

青少年ctf&#xff1a;PHP的XXE 1、打开网页是一个PHP版本页面 2、CTRLf搜索xml&#xff0c;发现2.8.0版本&#xff0c;含有xml漏洞 3、bp抓包 4、使用代码出发bug GET /simplexml_load_string.php HTTP/1.1 补充&#xff1a; <?xml version"1.0" encoding&quo…...

设计模式-解释器模式

作者持续关注 WPS二次开发专题系列&#xff0c;持续为大家带来更多有价值的WPS开发技术细节&#xff0c;如果能够帮助到您&#xff0c;请帮忙来个一键三连&#xff0c;更多问题请联系我&#xff08;QQ:250325397&#xff09; 定义 解释器模式&#xff08;Interpreter Pattern&…...

NDIS驱动程序堆栈

NDIS 6.0 引入了暂停和重启驱动程序堆栈的功能。 若要支持 NDIS 6.0 提供的堆栈管理功能&#xff0c;必须重写旧版驱动程序。 NDIS 6.0 还引入了 NDIS Filter驱动程序。 Filter驱动程序可以监视和修改协议驱动程序与微型端口驱动程序之间的交互。 与 NDIS 5 相比&#xff0c;F…...

大数据开发面试题【数仓篇】

197、数据仓库和传统数据库区别 由于历史数据使用频率过低&#xff0c;导致数据堆积&#xff0c;查询性能下降&#xff1b;用于查询分析&#xff0c;涉及大量的历史数据&#xff0c;数据仓库中的数据一般来日志文件和事务 数据库是跟业务挂钩的&#xff0c;数据库不可能装下一…...

Leetcode刷题笔记5

76. 最小覆盖子串 76. 最小覆盖子串 - 力扣&#xff08;LeetCode&#xff09; 解法一&#xff1a; 暴力枚举 哈希表 先定义left和right&#xff0c;可以在随机位置 枚举一个位置向后找&#xff0c;找到一个位置之后&#xff0c;发现这段区间是一个最小的区间之后&#xff0c…...

【Qt】Qt中的信号槽

一、信号和槽概述 信号槽是Qt矿建引以为豪的机制之一。 所谓信号槽&#xff0c;实际上就是观察者模式&#xff08;发布——订阅模式&#xff09;。当某个事件发生之后&#xff0c;比如&#xff0c;按钮检测到自己被点击了一下&#xff0c;它就会发出一个信号。这种发出的信号是…...

VsCode个人插件

Auto Rename Tag > 同时修改标签 Rainbow Brackets > 不同层级不同括号颜色 Dracula Official > 个人比较喜欢的一款主题 Error Lens > 错误信息显示 ES7REACT/Redux/React-Native>react开发插件 ESLINT Indenticator>方便看结构 Prettier Formatter …...

Docker环境安装并使用Elasticsearch

1、拉取es docker pull elasticsearch:7.10.12、查看镜像 docker images3、启动es docker run -d --name esearch -p 9200:9200 -p 9300:9300 elasticsearch:7.10.14、如果启动ES时出现一下问题 Unable to find image docker.elastic.co/elasticsearch/elasticsearch:7.10.…...

中心渗透Ⅱ

cs与msf权限传递以及mimikatz抓取win2012明文密码 使用Cobalt Strike抓取win2012明文密码&#xff0c;将会话传递到Metasploit Framework上 1.cs生成木马并使目标服务器中马 建立监听生成木马 2.抓取目标主机的明文密码 通过修改注册表来让Wdigest Auth保存明文口令 shell …...

【webrtc】RtpToNtpEstimator:最小二乘法、ntp估计及c++实例

上一篇: 【webrtc】RtpToNtpEstimator:将 RTP 时间戳映射到 NTP 时间 分析了最小二乘法的实现及对rtp到ntp的映射计算的调用流程 基于最小二乘法进行估计 RtpToNtpEstimator::Estimate G:\CDN\rtcCli\m98\src\system_wrappers\source\rtp_to_ntp_estimator.cc RtpToNtpEstima…...

【DevOps】Elasticsearch在Ubuntu 20.04上的安装与配置:详细指南

目录 一、ES 简介 1、核心概念 2、工作原理 3、 优势 二、ES 在 Ubuntu 20.04 上的安装 1、安装 Java 2、下载 ES 安装包 3、创建 ES 用户 4 、解压安装包 5、 配置 ES 6、 启动 ES 7、验证安装 三、ES 常用命令 1、创建索引 2、 插入文档 3、查询文档 四、ES…...

windows内存管理

一 windows系统的内存管理涉及哪些 1.1 虚拟内存管理机制 windows操作系统使用虚拟内存技术&#xff0c;将磁盘文件&#xff0c;通过映射对象&#xff08;存储在物理内存&#xff09;关联&#xff0c;映射到虚拟内存作为文件试图。即用户操作"虚拟内存中File View Objec…...

c++ 将指针转换为 void* 后,转换为怎么判断原指针类型?

当将指针转换为void后&#xff0c;擦除了指针所指向对象的类型信息&#xff0c;因此无法通过void指针来判断原始指针的类型。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程&#xff0c;不妨点个关注&#xff0c;给个…...

Swift 属性

属性 一、存储属性1、常量结构体实例的存储属性2、延时加载存储属性3、存储属性和实例变量 二、计算属性1、简化 Setter 声明2、简化 Getter 声明3、只读计算属性 三、属性观察器四、属性包装器1、设置被包装属性的初始值2、从属性包装器中呈现一个值 五、全局变量和局部变量六…...

基于maxkey接入jeecgboot并实现账户同步

1. 注册应用 1.1 在统一认证中心注册第三方应用 1.1.1 填写应用名和登录地址 1.1.2 填写认证地址授权方式和作用域 1.1.3 选择权限范围并提交 1.2 配置访问权限 1.2.1 指定用户组 1.1.2 选择注册的应用 1.1.3 在单点登录认证页面查看添加的应用 1.3 同步一个第三方应用的账号…...

kafka Kerberos集群环境部署验证

背景 公司需要对kafka环境进行安全验证,目前考虑到的方案有Kerberos和SSL和SASL_SSL,最终考虑到安全和功能的丰富度,我们最终选择了SASL_SSL方案。处于知识积累的角度,记录一下kafka keberos安装部署的步骤。 机器规划 目前测试环境公搭建了三台kafka主机服务,现在将详细…...

[C++]debug介绍+debug时如何查看指针指向内存处的值

一、简介 预备工具和知识&#xff1a;使用使用VSCode使用Debug。 本文简介&#xff1a;本文将简要介绍debug中Continue&#xff0c;Step Over&#xff0c;Step Into和Restart的功能。并介绍如何在debug时查看动态内存地址&#xff08;指针&#xff09;的值&#xff1b; 二、D…...

AI学习指南数学工具篇-凸优化在支持逻辑回归中的应用

AI学习指南数学工具篇-凸优化在支持逻辑回归中的应用 一、引言 在人工智能领域&#xff0c;逻辑回归是一种常见的分类算法&#xff0c;它通过学习样本数据的特征和标签之间的关系&#xff0c;来进行分类预测。而在逻辑回归算法中&#xff0c;凸优化是一种重要的数学工具&…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...

鸿蒙Navigation路由导航-基本使用介绍

1. Navigation介绍 Navigation组件是路由导航的根视图容器&#xff0c;一般作为Page页面的根容器使用&#xff0c;其内部默认包含了标题栏、内容区和工具栏&#xff0c;其中内容区默认首页显示导航内容&#xff08;Navigation的子组件&#xff09;或非首页显示&#xff08;Nav…...