QT控件 修改QtTreePropertyBrowser自定义属性编辑器源码,添加第一列标题勾选,按钮,右键菜单事件等功能
头阵子遇到一个需要修改QtTreePropertyBrowser控件的需求,QT开发做这么久了,这个控件倒是第一次用,费了点时间研究,在这里做个简单的总结。
QtTreePropertyBrowser控件 是 Qt 解决方案 (Qt Solutions) 中的一个组件,用于创建和管理属性浏览器界面。它提供了一个树形结构的属性编辑器,能实现自定义属性的编辑,支持大部分QVariant数据类型,
以前实现属性编辑器这种功能我都是使用的QTreeWidget实现的,但是有了QtTreePropertyBrowser控件这个控件,功能实现起来就简单了。
目录导读
- 前言
- 源码修改
- Qss样式支持 修改
- QComboBox 支持qss修改项行高
- 修改QtTreePropertyBrowser控件的每行高度
- 修改控件
- 添加标题允许勾选,添加设置按钮
- 设置修改自定义属性表 表头名称,获取QtTreeWidget控件等
- 根据鼠标坐标 获取选中属性
- 调用示例
前言
QtTreePropertyBrowser控件 不在QT的的UI设计器里面,如果要使用QtTreePropertyBrowser控件,需要注意到安装目录下的Src文件夹中查找(前提是安装qt的时候下载了Src源码文件)
- 参考目录:
(在Pro头文件夹中添加)
include($$[QT_INSTALL_PREFIX]/../Src/qttools/src/shared/qtpropertybrowser/qtpropertybrowser.pri)
- 支持的属性数据类型:
大部分QVariant数据类型,包括点,矩形,时间,字体,颜色等都支持在线编辑修改
默认已处理类型:
QVariant::Int
QVariant::Double
QVariant::Bool
QVariant::String
QVariant::Date
QVariant::Time
QVariant::DateTime
QVariant::KeySequence
QVariant::Char
QVariant::Locale
QVariant::Point
QVariant::PointF
QVariant::Size
QVariant::SizeF
QVariant::Rect
QVariant::RectF
QVariant::Color
QVariant::SizePolicy
QVariant::Font
QVariant::Cursor
- 实现效果:
通过对QtTreePropertyBrowser控件的源码简单修改,实现添加标题勾选,单击按钮,右键事件等功能。
需要注意的是 不同QT版本下的QtTreePropertyBrowser控件源码,不一定能直接编译 ,
使用时最好使用同一版本下的源码文件,
例如我使用的Qt5.13.1版本的QtTreePropertyBrowser控件源码在Qt5.15.2版本下Msvc2019编译器无法编译!
相关参考:
官方案例 qtpropertybrowser/examples
详解Qt5.12.9属性表控件:QtPropertyBrowser的使用示例/折叠/展开/小数位数/QSS样式/标题修改/选中行号等
源码修改
因为新添加的标题勾选,按钮,右键菜单这些功能改动不大,
不需要动QtTreePropertyBrowser控件的关键代码,只需要简单修改几行就可以了。
Qss样式支持 修改
修改qteditorfactory.cpp 文件 1919行
添加 editor->setView(new QListView());
如图示:
让多选项的行高能够修改
QSS:QComboBox QAbstractItemView::item{height:30px;}
QtTreePropertyBrowser控件默认是不支持设置行高的,即使我通过修改内部变量的QTreeWidget控件修改行高,也不支持。因为内置的QtPropertyEditorDelegate 委托阻止了设置行高。
修改 qttreepropertybrowser.cpp文件 382行
修改 sizeHint(const QStyleOptionViewItem &option,const QModelIndex &index) const函数
QSize QtPropertyEditorDelegate::sizeHint(const QStyleOptionViewItem &option,const QModelIndex &index) const
{//add to 2025-04-17 为了获取qss的heigth高度兼容// 获取 QTreeView 的样式表QTreeView *treeView = qobject_cast<QTreeView*>(parent());if (!treeView) {return QItemDelegate::sizeHint(option, index) + QSize(3,4); // 默认大小}// 获取样式表中的高度QStyleOptionViewItem opt = option;// 从样式中获取大小QSize size = treeView->style()->sizeFromContents(QStyle::CT_ItemViewItem, &opt, QSize(), treeView);return size;
}
如图示:
QSS:QTreeWidget::item{ background: #1d1f20; height:30px; }
修改控件
添加标题勾选本质上是启用QTreeWidgetItem类的setCheckState方法,并且监控itemChanged(QTreeWidgetItem* ,int )
事件响应,
添加按钮是在QTreeWidgetItem添加一个QPushButton按钮
修改源码:
- 修改qtpropertybrowser.cpp文件,修改QtPropertyPrivate 私有类
class QtPropertyPrivate
{
public:QtPropertyPrivate(QtAbstractPropertyManager *manager) : m_enabled(true), m_modified(false),m_ischecked(Qt::PartiallyChecked),m_ispushbutton(false), m_manager(manager) {}QtProperty *q_ptr;QSet<QtProperty *> m_parentItems;QList<QtProperty *> m_subItems;QString m_valueToolTip;QString m_descriptionToolTip;QString m_statusTip;QString m_whatsThis;QString m_name;bool m_enabled;bool m_modified;//! 是否可选Qt::CheckState m_ischecked;//! 是否作为一个按钮bool m_ispushbutton;QtAbstractPropertyManager * const m_manager;
};
- 修改 qtpropertybrowser.h文件,修改QtProperty类,添加修改属性方法
//追加属性
//! 因为使用的是 QTreeWidgetItem 的勾选事件,修改此属性不会触发信号
//!Qt::CheckState isChecked() const;
//!void setChecked(Qt::CheckState checked);
//! 设置作为一个button按钮 -后面的按钮使用
//!bool isPushbutton() const;
//!void SetPushbutton();Qt::CheckState QtProperty::isChecked() const
{return d_ptr->m_ischecked;
}
void QtProperty::setChecked(Qt::CheckState checked)
{d_ptr->m_ischecked=checked;//propertyChanged();
}bool QtProperty::isPushbutton() const
{return d_ptr->m_ispushbutton;
}
void QtProperty::SetPushbutton()
{d_ptr->m_ispushbutton=true;//propertyChanged();
}
- 修改qttreepropertybrowser.cpp文件 563行 修改QtTreePropertyBrowserPrivate类中的propertyInserted方法用于启用勾选,并根据状态判断是否插入按钮
void QtTreePropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex)
{//! 因为绑定了item修改事件 所以刚开始时禁止信号传递m_treeWidget->blockSignals(true);QTreeWidgetItem *afterItem = m_indexToItem.value(afterIndex);QTreeWidgetItem *parentItem = m_indexToItem.value(index->parent());QTreeWidgetItem *newItem = 0;if (parentItem) {newItem = new QTreeWidgetItem(parentItem, afterItem);} else {newItem = new QTreeWidgetItem(m_treeWidget, afterItem);}//add 是否启用勾选if(index->property()->isChecked()!=Qt::PartiallyChecked){Qt::CheckState checkstate=index->property()->isChecked();newItem->setCheckState(0,checkstate);}m_itemToIndex[newItem] = index;m_indexToItem[index] = newItem;newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);newItem->setExpanded(true);updateItem(newItem);//add pushbutton 插入一个按钮if(index->property()->isPushbutton()){newItem->setText(0,"");QPushButton* pubtton=new QPushButton();const QString descriptionToolTip = index->property()->descriptionToolTip();const QString propertyName = index->property()->propertyName();pubtton->setToolTip(descriptionToolTip.isEmpty() ? propertyName : descriptionToolTip);pubtton->setStatusTip(index->property()->statusTip());pubtton->setWhatsThis(index->property()->whatsThis());pubtton->setText(propertyName);m_indexToPushButton.insert(pubtton,newItem);//! 绑定 点击信号槽QObject::connect(pubtton,&QPushButton::pressed,[=](){emit q_ptr->itemPressedupdate(m_itemToIndex[m_indexToPushButton[pubtton]]->property());});m_treeWidget->setItemWidget(newItem,1,pubtton);}m_treeWidget->blockSignals(false);
}
- 添加绑定itemChanged信号槽,用于监控勾选状态改变
修改QtTreePropertyBrowser类和QtTreePropertyBrowserPrivate类
//! hpp
//! 追加内容
class QtTreePropertyBrowser : public QtAbstractPropertyBrowser
{Q_SIGNALS://! 选中状态改变void itemCheckStateupdate(QtProperty *item);//! 按钮按下 -某个按钮被按下触发事件void itemPressedupdate(QtProperty *item);
private://! 获取勾选状态改变Q_PRIVATE_SLOT(d_func(), void slotitemChanged(QTreeWidgetItem* item,int col))}//! cpp
class QtTreePropertyBrowserPrivate
{//! 追加修改QtTreePropertyBrowserPrivate类public://! 勾选改变void slotitemChanged(QTreeWidgetItem *item, int column);private://! 创建一个变量 用于保存点击的属性项QMap<QPushButton *, QTreeWidgetItem *> m_indexToPushButton;
}//! init 方法绑定信号
void QtTreePropertyBrowserPrivate::init(QWidget *parent)
{//! 添加-勾选改变状态事件QObject::connect(m_treeWidget, SIGNAL(itemChanged(QTreeWidgetItem* ,int )), q_ptr, SLOT(slotitemChanged(QTreeWidgetItem* ,int )));
}//状态改变发送信号
void QtTreePropertyBrowserPrivate::slotitemChanged(QTreeWidgetItem *item, int column)
{if(column==0){QtBrowserItem *browserItem = m_itemToIndex[item];if(browserItem && !browserItem->property()->hasValue()){if(browserItem->property()->isChecked() != Qt::PartiallyChecked){browserItem->property()->setChecked(item->checkState(column));emit q_ptr->itemCheckStateupdate(browserItem->property());}}}
}
QTreeWidget* QtTreePropertyBrowser::getPropertyTreeWidget()
{return d_ptr->treeWidget();
}//! 修改标题
//! ui->widget_AttriTree->setHeaderLabels(QStringList()<<"属性"<<"业务值");
void QtTreePropertyBrowser::setHeaderLabels(QStringList Headers)
{return d_ptr->m_treeWidget->setHeaderLabels(Headers);
}
QtProperty * QtTreePropertyBrowser::getPropertybyPointf(QPoint pos)
{QTreeWidgetItem * item= d_ptr->m_treeWidget->itemAt(QPoint(pos.x(),pos.y()-d_ptr->m_treeWidget->header()->height()));if(item){if(d_ptr->m_itemToIndex[item])return d_ptr->m_itemToIndex[item]->property();else{if(d_ptr->m_itemToIndex[item->parent()])return d_ptr->m_itemToIndex[item->parent()]->property();}}return nullptr;
}
如图示:
调用示例
- 绑定编辑工厂和属性节点管理
//! 属性节点管理//! QtVariantPropertyManager *m_pVarMgrEdit;//! 修改数据类型 工厂//! QtVariantEditorFactory *m_pVarFactory;
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);m_pVarMgrEdit = new QtVariantPropertyManager(ui->widget_AttriTree);//关联factory,属性可以修改m_pVarFactory = new QtVariantEditorFactory(ui->widget_AttriTree);//connect(m_pVarMgrEdit,&QtVariantPropertyManager::valueChanged,this, &ProPertyWindow::onValueChanged);//绑定信号槽,当值改变的时候会发送信号//! LoadXml();//! qDebug()<<"XML 文件解析完毕! ! ! ";//将一个工厂与manger关联起来,即可修改内容。ui->widget_AttriTree->setFactoryForManager(m_pVarMgrEdit,m_pVarFactory);
// ui->widget_AttriTree->setAlternatingRowColors(false);//! 修改标题ui->widget_AttriTree->setHeaderLabels(QStringList()<<"属性"<<"业务值");//! 默认事件connect(m_pVarMgrEdit,&QtVariantPropertyManager::valueChanged,this,[&](QtProperty *property, const QVariant &value){qDebug()<<"propertyName: "<< property->propertyName()<<" value: "<<value;});//! 勾选状态改变connect(ui->widget_AttriTree,&QtTreePropertyBrowser::itemCheckStateupdate,this,[&](QtProperty *item){});//! 点击事件connect(ui->widget_AttriTree,&QtTreePropertyBrowser::itemPressedupdate,this,[&](QtProperty *item){});
}
- 绑定数据示例:
//QDomElement xml文件解析
void MainWindow::ParseItem(QDomElement ItemNode,QtVariantProperty *parent)
{if(!ItemNode.hasAttribute("name"))return;QString propertyName=ItemNode.attribute("name").trimmed();QString type=ItemNode.attribute("type","null").toLower().trimmed();QString check=ItemNode.attribute("check","null").toLower().trimmed();QtVariantProperty *item=nullptr;if(type=="float"||type=="double"){item = m_pVarMgrEdit->addProperty(QVariant::Double,propertyName);item->setValue(ItemNode.text().toDouble());}else if(type=="comboxlist"){QStringList enumNames;int CurrentIndex=0;QDomNodeList childnode= ItemNode.childNodes();for(int j=0;j<childnode.count();j++){if (childnode.item(j).isElement()){QDomElement element = childnode.item(j).toElement();if(element.tagName().toLower()=="data"){enumNames<<element.text();if(element.attribute("isSelect","false").toLower()=="true")CurrentIndex=enumNames.count()-1;}}}item = m_pVarMgrEdit->addProperty(QtVariantPropertyManager::enumTypeId(), propertyName);item ->setAttribute(QLatin1String("enumNames"), enumNames);item ->setValue(CurrentIndex);}else if(type=="int"){item = m_pVarMgrEdit->addProperty(QVariant::Int,propertyName);item->setValue(ItemNode.text().toInt());}else if(type=="datetime"){item = m_pVarMgrEdit->addProperty(QVariant::DateTime,propertyName);item->setValue(QDateTime::fromString(ItemNode.text(),"yyyy/MM/dd hh:mm:ss"));}else if(type=="string"){item = m_pVarMgrEdit->addProperty(QVariant::String,propertyName);item->setValue(ItemNode.text());}else if(type=="pointf"){item = m_pVarMgrEdit->addProperty(QVariant::PointF,propertyName);QStringList poinfs=ItemNode.text().split(',');item->setValue(QPointF(poinfs[0].toDouble(),poinfs[1].toDouble()));}else if(type=="rectf"){item = m_pVarMgrEdit->addProperty(QVariant::RectF,propertyName);QStringList poinfs=ItemNode.text().split(',');item->setValue(QRectF(poinfs[0].toDouble(),poinfs[1].toDouble(),poinfs[2].toDouble(),poinfs[3].toDouble()));}else if(type=="bool"){item = m_pVarMgrEdit->addProperty(QVariant::Bool,propertyName);item->setValue(ItemNode.text()=="false"?false:true);}else if(type=="color"){item = m_pVarMgrEdit->addProperty(QVariant::Color,propertyName);item->setValue(QColor(ItemNode.text()));}else if(type=="pushbutton"){//! 添加按钮事件item = m_pVarMgrEdit->addProperty(QtVariantPropertyManager::groupTypeId(),propertyName);item->SetPushbutton();}elseitem = m_pVarMgrEdit->addProperty(QtVariantPropertyManager::groupTypeId(),propertyName);if(_ISNULL_(item))return;//! 添加首项勾选if(check!="null"){
// qDebug()<<"propertyName: "<<propertyName<<" check: "<<check;item->setChecked(check.toLower().trimmed()=="true"?Qt::Checked:Qt::Unchecked);}if(!_ISNULL_(parent))parent->addSubProperty(item);elseui->widget_AttriTree->addProperty(item);}
相关文章:
QT控件 修改QtTreePropertyBrowser自定义属性编辑器源码,添加第一列标题勾选,按钮,右键菜单事件等功能
头阵子遇到一个需要修改QtTreePropertyBrowser控件的需求,QT开发做这么久了,这个控件倒是第一次用,费了点时间研究,在这里做个简单的总结。 QtTreePropertyBrowser控件 是 Qt 解决方案 (Qt Solutions) 中的一个组件,用…...
MFC工具栏CToolBar从专家到小白
CToolBar m_wndTool; //创建控件 m_wndTool.CreateEx(this, TBSTYLE_FLAT|TBSTYLE_NOPREFIX, WS_CHILD | WS_VISIBLE | CBRS_FLYBY | CBRS_TOP | CBRS_SIZE_DYNAMIC); //加载工具栏资源 m_wndTool.LoadToolBar(IDR_TOOL_LOAD) //在.rc中定义:IDR_TOOL_LOAD BITMAP …...
Golang 项目平滑重启
引言 平滑重启(Graceful Restart)技术作为一种常用的解决方案,通过允许新进程接管而不中断现有的请求,确保了系统的稳定运行和业务连续性。同时目前公司的服务重启绝大部分也都适用的 go 的平滑重启技术。 本部分将对平滑重启的…...
Vue2 插槽 Slot
提示:插槽的目的是让我买原来的设备具备更多的扩展性。 文章目录 前言在组件中定义插槽(子组件视角)1. 默认插槽2. 具名插槽(带名称的插槽)3. 作用域插槽(带数据的插槽) 使用插槽(父…...
关于sqlsugar实体多层List映射的问题
如上图所示,当一个主表(crm_fina_pay_req)的子表list<文件附件关系表>( List<crm_fina_payreq_evidofpay_relation> )中,还包含有sysfile(SysFile SysFiles)类型的文件信…...
使用stm32cubeide stm32f407 lan8720a freertos lwip 实现udp client网络数据转串口数据过程详解
1前言 项目需要使用MCU实现网络功能,后续确定方案stm32f407 外接lan8720a实现硬件平台搭建,针对lan8720a也是用的比较多的phy,网上比较多的开发板,硬件上都是选用了这个phy,项目周期比较短,选用了这个常用…...
LangChain4j(4):预设角色(系统消息SystemMessage)
1 预设角色(系统消息SystemMessage) 基础大模型是没有目的性的, 你聊什么给什么,但是如果我们开发的事一个智能票务助手, 我需要他以一个票务助手的角色跟我对话, 并且在我跟他说”退票”的时候, 让大模型一定要告诉我…...
自然语言处理利器NLTK:从入门到核心功能解析
文章目录 一、NLP领域的基石工具包二、NLTK核心模块全景解析1 数据获取与预处理2 语言特征发现3 语义与推理 三、设计哲学与架构优势1 四维设计原则2 性能优化策略 四、典型应用场景1 学术研究2 工业实践 五、生态系统与未来演进 一、NLP领域的基石工具包 自然语言工具包&…...
常见接口协议介绍
1. I2C(Inter-Integrated Circuit) 定义:两线制串行总线(SDA数据线 SCL时钟线),支持主从模式多设备通信。特点: 地址机制:每个设备有唯一地址,主设备通过地址选择从设备…...
宝塔面板使用CDN 部署后获取真实客户端 IP教程
在宝塔面板环境中配置 CDN 加速服务后,服务器日志默认记录的是 CDN 节点 IP,这给网站流量分析带来不便。本文将为您提供多种解决方案,帮助您在 CDN 生效的同时获取真实访客 IP。 一、Nginx 配置调整方案 日志格式优化 在宝塔面板中打开 Ngi…...
生鲜果蔬便利店实体零售门店商城小程序
——线上线下融合赋能社区零售新生态 随着新零售模式的深化和消费者需求的升级,生鲜果蔬便利店亟需通过数字化工具实现经营效率与用户体验的双重提升。结合线下实体门店与线上商城的一体化小程序,成为行业转型的核心工具。以下从功能模块、运营策略及行…...
C++(初阶)(十)——vector模拟实现
vector vector构造尾插(删)和扩容inert(插入)迭代器失效erase(删除)resize(调整空间)深浅拷贝迭代器拷贝和赋值(v2(v1)和v1 v3)多个数据插入迭代器区间初始化…...
利用解析差异SSRF + sqlite注入 + waf逻辑漏洞 -- xyctf 2025 fate WP
本文章附带TP(Thinking Process)! #!/usr/bin/env python3 # 导入所需的库 import flask # Flask web框架 import sqlite3 # SQLite数据库操作 import requests # HTTP请求库 import string # 字符串处理 import json # JSON处理app flask.Flask(__name__) # 创建Flask应…...
VScode无法激活conda虚拟环境,不显示虚拟环境名称
在VScode中终端中激活环境时出现下面的情况 PS F:\Model\stMMR-main> conda activate env_mamba usage: conda-script.py [-h] [--no-plugins] [-V] COMMAND ... conda-script.py: error: argument COMMAND: invalid choice: activate (choose from clean, compare, config…...
vscode Colipot 编程助手
1、登录到colipot,以github账号,关联登录 点击【continue】按钮,继续。 点击【打开Visual Studio Code】,回到vscode中。 2、问一下11? 可以看出,很聪明,一下子就算出来了。 3、帮我们写一个文件…...
vscode中REST Client插件
最近发现vscode中REST Client插件也可以测试接口 简介 在 VS Code 中,REST Client 是一个非常受欢迎的插件,用于测试和调试 RESTful API。以下是关于该插件的安装、使用和功能的详细介绍: 安装 REST Client 插件 打开 VS Code。点击左侧的扩…...
路由器工作在OSI模型的哪一层?
路由器主要工作在OSI模型的第三层,即网络层。网络层的主要功能是将数据包从源地址路由到目标地址,路由器通过检查数据包中的目标IP地址,并根据路由表确定最佳路径来实现这一功能。 路由器的主要功能: a、路由决策:路…...
(PROFINET 转 EtherCAT)EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关
型号 协议转换通信网关 PROFINET 转 EtherCAT MS-GW31 概述 MS-GW31 是 PROFINET 和 EtherCAT 协议转换网关,为用户提供两种不同通讯协议的 PLC 进行数据交互的解决方案,可以轻松容易将 EtherCAT 网络接入 PROFINET 网络中,方便扩展&…...
【教程】MacBook 安装 VSCode 并连接远程服务器
目录 需求步骤问题处理 需求 在 Mac 上安装 VSCode,并连接跳板机和服务器。 步骤 Step1:从VSCode官网(https://code.visualstudio.com/download)下载安装包: Step2:下载完成之后,直接双击就能…...
Solidity基础入门—web3
Remix介绍 官网地址 Remix 是一个基于浏览器的 Solidity 开发环境,主要用于编写、测试、调试和部署以太坊智能合约。 Solidity基本数据类型 类型说明示例uint / int无符号 / 有符号整数uint256, int8, int256bool布尔类型(true / false)bo…...
微信小程序 request 流式数据处理
什么是流式数据处理? 流式数据处理(Streaming Data)指逐步接收并处理数据片段的技术,无需等待全部数据加载完成。适用于大文件下载、实时日志、AI生成报告等场景,可显著降低内存占用并提升用户体验。 微信小程序中的…...
Kotlin与HttpClient编写视频爬虫
想用Apache HttpClient库和Kotlin语言写一个视频爬虫。首先,我需要确定用户的具体需求。视频爬虫通常涉及发送HTTP请求,解析网页内容,提取视频链接,然后下载视频。可能需要处理不同的网站结构,甚至可能需要处理动态加载…...
数据结构:通俗解释AOE 网中事件的最早发生时间和最迟发生时间
1. 事件的最早发生时间 在 AOE 网(Activity On Edge Network,边表示活动的网络)中,事件的最早发生时间指从源点(起点)到该事件结点的最长路径长度(即所需时间)。它决定了所有以该事…...
爬虫中遇到的问题
网页假请求导致的阻塞 可以在requests请求当中添加timeout参数,来让网站重新请求 在爬虫请求中,timeout参数的主要作用是控制请求的最大等待时间,避免因服务器响应缓慢或网络问题导致程序长时间阻塞,从而提升爬虫的效率和稳定性…...
聊一聊没有接口文档时如何开展测试
目录 一、前期准备与信息收集 二、使用抓包工具分析接口 三、逆向工程构造测试用例 四、安全测试 五、 模糊测试(Fuzz Testing) 六、记录并维护发现的接口信息 七、 推动团队规范流程 其它注意事项 在我们进行接口测试时,总会遇到各种…...
第一部分:MCP协议与多智能体系统基础-第1课:MCP服务协议核心架构解析
以下是为《MCP服务协议核心架构解析》设计的课件内容,采用“概念解析→代码实践→运行验证”三段式教学结构,结合可视化图表与可运行代码示例,增强学生对MCP协议核心组件的理解与实操能力: 一、课程导入:MCP协议定位与…...
WEB安全--内网渗透--捕获NET-NTLMv2 Hash
一、前言 在LM&NTLM基础篇中我们了解到了NTLM协议的流程与加密的方式,以及具体的在type3的response中Net-ntlm hash v2的生成方式。 思考: 如果我们入侵的服务器中有域管理员的登录后的密码缓存,那就能用工具(mimikatz&…...
使用 J-Flash 读取芯片 Flash 数据的方法
基本读取步骤 硬件连接 确保 J-Link 调试器正确连接到目标板 给目标板供电(可通过 J-Link 供电或外部电源) 创建/打开项目 启动 J-Flash 软件 选择 "File" > "New Project" 创建新项目 选择正确的目标芯片型号(或…...
Spring MVC 返回 JSON 视图的方式及对比(6种)
Spring MVC 返回 JSON 视图的方式及对比(新增 MappingJackson2JsonView) 1. 方式一:ResponseBody 注解 作用:直接返回对象,由消息转换器(如 Jackson)序列化为 JSON。 适用场景:简单…...
SpringMVC的数据响应
1)页面跳转 直接返回字符串 通过ModelAndView对象返回 //方式三(model和view拆开)RequestMapping("/quick4")public String save4(Model model){model.addAttribute("username","lisi3");return "success";}//方式二RequestMapping(&…...
GraphRAG与知识图谱
一、GraphRAG介绍 1.1 什么是 Graph RAG? Graph RAG(Retrieval-Augmented Generation),是一种基于知识图谱的检索增强技术, 通过构建图模型的知识表达,将实体和关系之间的联系用图的形式进行展示ÿ…...
hive通过元数据库删除分区操作步骤
删除分区失败: alter table proj_60_finance.dwd_fm_ma_kpi_di_mm drop partition(year2025,month0-3,typeADJ); 1、查询分区的DB_ID、TBL_ID – 获取数据库ID-26110 SELECT DB_ID FROM DBS WHERE NAME ‘proj_60_finance’; – 获取表ID-307194 SELECT TBL_ID FR…...
LINUX 5 cat du head tail wc 计算机拓扑结构 计算机网络 服务器 计算机硬件
计算机网络 计算机拓扑结构 计算机按性能指标分:巨型机、大型机、小型机、微型机。大型机、小型机安全稳定,小型机用于邮件服务器 Unix系统。按用途分:专用机、通用机 计算机网络:局域网‘、广域网 通信协议’ 计算机终端、客户端…...
flink 增量快照同步文件引用关系和恢复分析
文章目录 文件引用分析相关代码分析从state 恢复,以rocksdb为例不修改并行度修改并行度keyGroupRange过程问题 文件引用分析 每次生成的checkpoint 里都会有所有文件的引用信息 问题,引用分析里如何把f1,f2去掉了,可以参考下面的代码&#…...
属性修改器 (AttributeModifier)
主页面设置组件 import { MyButtonModifier } from ../datastore/MyButtonModifier;Entry ComponentV2 struct MainPage {// 支持用状态装饰器修饰,行为和普通的对象一致Local modifier: MyButtonModifier new MyButtonModifier();build() {Column() {Button(&quo…...
汽车BMS技术分享及其HIL测试方案
一、BMS技术简介 在全球碳中和目标的战略驱动下,新能源汽车产业正以指数级速度重塑交通出行格局。动力电池作为电动汽车的"心脏",其性能与安全性不仅直接决定了车辆的续航里程、使用寿命等关键指标,更深刻影响着消费者对电动汽车的…...
电网电能质量分析:原理、算法及实际应用
一、引言 在现代社会,电力供应的稳定性和可靠性对工业生产、社会生活的各个方面都至关重要。电能质量作为衡量电力系统供电能力的关键指标,其优劣直接影响到电力设备的运行效率、使用寿命以及生产过程的稳定性。随着电力系统规模的不断扩大,新…...
PyCharm Community社区版链接WSL虚拟环境
#记录工作 在过去,PyCharm Community Edition(社区版)不具备链接 WSL 虚拟环境的功能,该功能仅在 PyCharm Professional(专业版)和企业版中提供。如今,从 PyCharm Community Edition 2024.3.5 …...
2026考研数学张宇武忠祥复习视频课,高数基础班+讲义PDF
2026考研数学武忠祥老师课(网盘):点击下方链接 2026考研数学武忠祥网课(最新网盘) 一、基础阶段(3-5个月) 目标:搭建知识框架掌握基础题型 教材使用: 高数:…...
Spring Boot嵌入前端静态资源:从原理到实战的完整指南
在Java Spring Boot项目中集成前端静态资源是构建现代Web应用的必备技能。本文将深入解析Spring Boot的静态资源处理机制,通过实战案例演示完整的集成流程,并分享性能优化与安全加固的最佳实践。 一、Spring Boot静态资源处理原理 1.1 默认资源路径 S…...
DeepSeek对比ChatGPT有何改进,可以用更低成本计算
下面是基于DeepSeek公开论文和代码,与ChatGPT对比后总结的改进点,以及其为何能用更少算力训练大模型的解析。 https://arxiv.org/pdf/2412.19437 1. 改进点对比 1.1 架构稀疏化与混合专家(MoE)设计 DeepSeek采用稀疏激活与混合…...
JavaScript双问号操作符(??)详解,解决使用 || 时因类型转换带来的问题
目录 JavaScript双问号操作符(??)详解,解决使用||时因类型转换带来的问题 一、双问号操作符??的基础用法 1、传统方式的痛点 2、双问号操作符??的精确判断 3、双问号操作符??与逻辑或操作符||的对比 二、复杂场景下的空值处理 …...
Go语言从零构建SQL数据库(5)-Pratt解析算法:SQL表达式解析的核心引擎
Pratt解析算法:SQL表达式解析的核心引擎 1. 算法概述与工作原理 Pratt解析算法(自顶向下运算符优先级解析)是一种优雅的表达式解析方法,特别适合处理具有不同优先级运算符的复杂表达式。在我们的SQL解析器中,它负责解…...
数字政府与电子政务综合分析报告
数字政府与电子政务综合分析报告 一、引言 随着信息技术的飞速发展,数字政府和电子政务成为全球公共管理领域的重要趋势。数字政府和电子政务的建设不仅是提升政府治理能力的必然选择,也是推动国家治理现代化的重要途径。本文将对数字政府和电子政务进…...
服务器虚拟化技术深度解析:医药流通行业IT架构优化指南
一、服务器虚拟化的定义与原理 (一)技术定义:从物理到虚拟的资源重构 服务器虚拟化是通过软件层(Hypervisor)将物理服务器的CPU、内存、存储、网络等硬件资源抽象为逻辑资源池,分割成多个相互隔离的虚拟机…...
QT ARM 开发环境搭建
搭建 QT ARM 开发环境主要包括主机环境配置、交叉编译工具链安装、QT 库交叉编译和 QT Creator 配置几个步骤。以下是详细流程: 一. 主机环境准备 系统要求 推荐 Ubuntu 18.04/20.04 LTS 或更高版本 至少 50GB 可用磁盘空间 8GB 以上内存 安装基础依赖 sudo apt update sud…...
【设计模式】外观模式
简介 想象你要在家里看电影,需要做以下操作: 打开电视启动音响调暗灯光关闭窗帘 如果每次都要手动操作这些步骤会很麻烦。外观模式可以帮你将这些步骤封装成一个统一的接口,比如“一键观影模式”,你只需按一个按钮,…...
[特殊字符] 驱动开发硬核特训 · Day 5 - 深入解析 Platform Driver 驱动框架
主题:深入解析 Platform Driver 驱动框架 —— 从架构设计到工程实战 平台驱动(platform driver)是 Linux 内核中应用最广泛的一种设备驱动框架。它用于管理那些不依赖总线枚举机制的固定外设,如 GPIO 控制器、I2C 控制器、SPI 控…...
创意 Python 爱心代码
在编程的世界里,Python 以其简洁易用和丰富的库而备受喜爱。用 Python 编写爱心代码,不仅能展现编程的魅力,还能传递温暖与爱意。今天就来分享几种创意 Python 爱心代码。 一、基于turtle库绘制爱心 turtle库是 Python 内置的图形库&#x…...
【群晖】挂载小雅alist到AList网盘中
群晖开启远程 在命令行远程到主机 ssh 用户名主机名终端中执行下方命令创建一个在AList中挂载小雅所需要的token: docker exec -i xiaoya sqlite3 data/data.db <<EOF select value from x_setting_items where key "token"; EOF 如果报权限错误…...