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

[WTL/Win32]_[初级]_[如何设置ListView的列宽不出现水平滚动条]

场景

  1. 开发WTL/Win32的程序时,经常会用到表格控件CListViewCtrl。这个控件需要设置列的宽度,当用完100%的宽度来平均分配给列宽时,一加载数据多,就会出现垂直滚动条后,水平滚动条也会同时出现的问题。怎么设置才能让水平滚动条不出现?

图1
在这里插入图片描述

说明

  1. WTL的控件CListViewCtrl实际上就是Win32listview控件的封装。当行个数超过它的可见区域时,就会默认出现垂直滚动条。这个垂直滚动条也是占用了原本ListView的客户端区域,导致ListView的客户端区域宽度减少,也就是现在的客户端宽度 = 原来的客户端区域宽度-滑块的宽度

  2. 当然也可以在行数据超过可见区域时重新计算列宽度,只是这种做法需要在合适的时候进行判断行数据是否够多导致垂直滚动条出现。一般不建议做这个冗余的判断处理。

  3. 目前推荐的做法是布局ListView时,也就是设置它的列宽时,如果没有出现垂直滚动条,那么预留滚动条的宽度不分配给列宽。 以下是获取滑块宽度的做法:

  4. 关于WTL/Win32开发请参考我的课程 使用WTL进行Windows桌面应用开发

void CView::layoutListView()
{CRect rect;listview_.GetClientRect(&rect);auto width = rect.Width();listview_.SetColumnWidth(0, width*0.2);listview_.SetColumnWidth(1, width*0.3);listview_.SetColumnWidth(2, width*0.2);auto last = width * 0.3;if (buttonIsLayoutWithThumb_.GetCheck()) {auto thumbWidth = GetWindowVScrollBarThumbWidth(listview_, false);// 如果默认没有滚动条,减去滑块宽度。if (!thumbWidth) { thumbWidth = GetWindowVScrollBarThumbWidth(listview_, true);last = last - thumbWidth;}}listview_.SetColumnWidth(3, last);
}

例子

View.h

// View.h : interface of the CView class
//
/#pragma once#include <utility>
#include <string>
#include <vector>
#include <memory>
#include <atlmisc.h>
#include <atlctrls.h>
#include <atlctrlx.h>
#include <GdiPlus.h>using namespace std;enum
{kMyButtonId = WM_USER+1,kMyButtonId2,kMyButtonId3,kMyButtonId4,kMyListViewId
};class Photo
{
public:wstring name;wstring createDate;wstring path;wstring format;
};class CView : public CWindowImpl<CView>
{
public:DECLARE_WND_CLASS(NULL)BOOL PreTranslateMessage(MSG* pMsg);BEGIN_MSG_MAP_EX(CView)MSG_WM_CREATE(OnCreate)MSG_WM_SIZE(OnSize)MESSAGE_HANDLER(WM_PAINT, OnPaint)NOTIFY_HANDLER(kMyListViewId,NM_CLICK,OnNMClickListResult)NOTIFY_HANDLER(kMyListViewId,LVN_GETDISPINFO,OnGetListViewData)NOTIFY_HANDLER(kMyListViewId,LVN_ODCACHEHINT,OnPrepareListViewData)NOTIFY_HANDLER(kMyListViewId,LVN_ODFINDITEM,OnFindListViewData)COMMAND_RANGE_HANDLER_EX(kMyButtonId,kMyButtonId4,OnCommandIDHandlerEX)REFLECT_NOTIFICATIONS()END_MSG_MAP()protected:
// Handler prototypes (uncomment arguments if needed):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)int OnCreate(LPCREATESTRUCT lpCreateStruct);LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);void UpdateLayout();LRESULT OnNMClickListResult(int idCtrl,LPNMHDR pnmh,BOOL &bHandled);LRESULT OnGetListViewData(int idCtrl,LPNMHDR pnmh,BOOL &bHandled);LRESULT OnPrepareListViewData(int idCtrl,LPNMHDR pnmh,BOOL &bHandled);LRESULT OnFindListViewData(int idCtrl,LPNMHDR pnmh,BOOL &bHandled);void OnCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl);void OnSize(UINT nType, CSize size);void ReloadMockData(int count);void ReloadListView();protected:void layoutListView();static int GetWindowVScrollBarThumbWidth(HWND hwnd, bool bAutoShow);private:std::wstring GetControlText(HWND hwnd,wchar_t* buf = NULL);CListViewCtrl listview_;vector<shared_ptr<Photo>> photos_;CFont font_normal_;CFont font_bold_;CBrushHandle brush_white_;CBrushHandle brush_hollow_;CBrush brush_red_;CButton buttonIsLayoutWithThumb_;CButton buttonReloadMockData_;CButton buttonReloadMockData10_;CButton buttonReloadListView_;
};

View.cpp

// View.cpp : implementation of the CView class
//
/#include "stdafx.h"
#include "resource.h"
#include <utility>
#include <sstream>
#include <stdint.h>
#include <assert.h>
#include <Strsafe.h>#include "View.h"
#include <CommCtrl.h>
#include <string>
#include <regex>using namespace std;BOOL CView::PreTranslateMessage(MSG* pMsg)
{return FALSE;
}LRESULT CView::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{CPaintDC dc(m_hWnd);CMemoryDC mdc(dc,dc.m_ps.rcPaint);CRect rect_client;GetClientRect(&rect_client);mdc.FillSolidRect(rect_client,RGB(255,255,255));//TODO: Add your drawing code herereturn 0;
}static HFONT GetFont(int pixel,bool bold,const wchar_t* font_name)
{LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); // zero out structure lf.lfHeight = pixel; // request a 8-pixel-height fontif(bold){lf.lfWeight = FW_BOLD;  }lstrcpy(lf.lfFaceName, font_name); // request a face name "Arial"HFONT font = ::CreateFontIndirect(&lf);return font;
}std::wstring CView::GetControlText(HWND hwnd,wchar_t* buf)
{auto length = ::GetWindowTextLength(hwnd);bool bufNull = false;if(!buf){buf = new wchar_t[length+1]();bufNull = true;}::GetWindowText(hwnd,buf,length+1);std::wstring str(buf);if(bufNull)delete []buf;return str;
}static std::wstring GetProductBinDir()
{static wchar_t szbuf[MAX_PATH];  GetModuleFileName(NULL,szbuf,MAX_PATH);  PathRemoveFileSpec(szbuf);int length = lstrlen(szbuf);szbuf[length] = L'\\';szbuf[length+1] = 0;return std::wstring(szbuf);
}LRESULT CView::OnGetListViewData(int idCtrl,LPNMHDR pnmh,BOOL &bHandled)
{NMLVDISPINFO* plvdi = (NMLVDISPINFO*) pnmh;auto iItem = plvdi->item.iItem;if (-1 == iItem)return 0;auto count = photos_.size();if(!count || count <= iItem)return 0;auto photo = photos_[iItem];if(plvdi->item.mask & LVIF_TEXT){switch(plvdi->item.iSubItem){case 0:StringCchCopy(plvdi->item.pszText, plvdi->item.cchTextMax, to_wstring((int64_t)iItem+1).c_str());break;case 1:StringCchCopy(plvdi->item.pszText, plvdi->item.cchTextMax, photo->name.c_str());break;case 2:StringCchCopy(plvdi->item.pszText, plvdi->item.cchTextMax, photo->format.c_str());break;case 3:StringCchCopy(plvdi->item.pszText, plvdi->item.cchTextMax, photo->createDate.c_str());break;}}return 0;
}LRESULT CView::OnPrepareListViewData(int idCtrl,LPNMHDR pnmh,BOOL &bHandled)
{return 0;
}LRESULT CView::OnFindListViewData(int idCtrl,LPNMHDR pnmh,BOOL &bHandled)
{LPNMLVFINDITEM  pnmfi = (LPNMLVFINDITEM)pnmh;auto iItem = pnmfi->iStart;if (-1 == iItem)return -1;auto count = photos_.size();if(!count || count <= iItem)return -1;return 0;
}LRESULT CView::OnNMClickListResult(int idCtrl,LPNMHDR pnmh,BOOL &bHandled)
{return 0;
}void CView::OnCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
{switch(nID){case kMyButtonId3:{buttonIsLayoutWithThumb_.SetCheck(!buttonIsLayoutWithThumb_.GetCheck());ReloadListView();layoutListView();break;}case kMyButtonId:{ReloadMockData(10000);break;}case kMyButtonId4:{ReloadMockData(10);break;}case kMyButtonId2:{ReloadListView();break;}}
}void CView::ReloadListView()
{listview_.SetItemCount(0);photos_.clear();
}void CView::ReloadMockData(int count)
{wchar_t buf[MAX_PATH] = {0};LVCOLUMN co;memset(&co,0,sizeof(co));co.mask = LVCF_TEXT;co.pszText = buf;co.cchTextMax = MAX_PATH;listview_.GetColumn(1,&co);std::wstring c0Text(buf);listview_.GetColumn(2,&co);std::wstring c1Text(buf);listview_.GetColumn(3,&co);std::wstring c2Text(buf);static int index = 0;for(int i = 0; i< count;++i,++index){auto photo = new Photo();wsprintf(buf,(c0Text+L"-%d").c_str(),index);photo->name = buf;wsprintf(buf,(c1Text+L"-%d").c_str(),index);photo->format = buf;wsprintf(buf,(c2Text+L"-%d").c_str(),index);photo->createDate = buf;photos_.push_back(move(shared_ptr<Photo>(photo)));}listview_.SetItemCount(photos_.size());
}int CView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{font_normal_ = ::GetFont(16,false,L"Arial");font_bold_ = ::GetFont(16,true,L"Arial");brush_hollow_ = AtlGetStockBrush(HOLLOW_BRUSH);brush_white_ = AtlGetStockBrush(WHITE_BRUSH);brush_red_.CreateSolidBrush(RGB(255,0,0));// 1.创建CListViewCtrllistview_.Create(m_hWnd,0,NULL,WS_CHILD | WS_TABSTOP |WS_VISIBLE|LVS_ALIGNLEFT|LVS_REPORT|LVS_SHOWSELALWAYS|WS_BORDER|LVS_OWNERDATA,0,kMyListViewId);listview_.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_DOUBLEBUFFER);listview_.SetFont(font_normal_);auto header = listview_.GetHeader();header.SetFont(font_bold_);listview_.SetBkColor(RGB(255,255,255));listview_.InsertColumn(0,L"No.",LVCFMT_LEFT,0);listview_.InsertColumn(1,L"Name",LVCFMT_LEFT,0);listview_.InsertColumn(2,L"Format",LVCFMT_LEFT,0);listview_.InsertColumn(3,L"Create Date",LVCFMT_LEFT,0);// 2.创建按钮buttonIsLayoutWithThumb_.Create(m_hWnd, 0, L"布局列宽是否计算滑块宽度", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, 0, kMyButtonId3);buttonIsLayoutWithThumb_.SetFont(font_normal_);buttonReloadMockData_.Create(m_hWnd,0,L"加载新数据10000条",WS_CHILD|WS_VISIBLE,0,kMyButtonId);buttonReloadMockData_.SetFont(font_normal_);buttonReloadMockData10_.Create(m_hWnd, 0, L"加载新数据10条", WS_CHILD | WS_VISIBLE, 0, kMyButtonId4);buttonReloadMockData10_.SetFont(font_normal_);buttonReloadListView_.Create(m_hWnd,0,L"清空表格",WS_CHILD|WS_VISIBLE,0,kMyButtonId2);buttonReloadListView_.SetFont(font_normal_);return 0;
}int CView::GetWindowVScrollBarThumbWidth(HWND hwnd, bool bAutoShow)
{SCROLLBARINFO sb = { 0 };sb.cbSize = sizeof(SCROLLBARINFO);GetScrollBarInfo(hwnd, OBJID_VSCROLL, &sb);if (!bAutoShow)return sb.dxyLineButton;if (sb.dxyLineButton)return sb.dxyLineButton;::ShowScrollBar(hwnd, SB_VERT, TRUE);sb.cbSize = sizeof(SCROLLBARINFO);GetScrollBarInfo(hwnd, OBJID_VSCROLL, &sb);::ShowScrollBar(hwnd, SB_VERT, FALSE);return sb.dxyLineButton;
}void CView::layoutListView()
{CRect rect;listview_.GetClientRect(&rect);auto width = rect.Width();listview_.SetColumnWidth(0, width*0.2);listview_.SetColumnWidth(1, width*0.3);listview_.SetColumnWidth(2, width*0.2);auto last = width * 0.3;if (buttonIsLayoutWithThumb_.GetCheck()) {auto thumbWidth = GetWindowVScrollBarThumbWidth(listview_, false);if (!thumbWidth) {// 如果默认没有滚动条thumbWidth = GetWindowVScrollBarThumbWidth(listview_, true);last = last - thumbWidth;}}listview_.SetColumnWidth(3, last);
}void CView::OnSize(UINT nType, CSize size)
{if (!size.cx)return;UpdateLayout();
}void CView::UpdateLayout()
{CRect rect;GetClientRect(&rect);CClientDC dc(m_hWnd);dc.SelectFont(font_normal_);CSize sizeCheck;buttonIsLayoutWithThumb_.GetIdealSize(&sizeCheck);buttonIsLayoutWithThumb_.MoveWindow(CRect(20,2, sizeCheck.cx+20, sizeCheck.cy+2));CSize size_control(rect.Width() - 50,300);CRect rect_control = CRect(CPoint(20,20),size_control);listview_.MoveWindow(rect_control);layoutListView();CSize size_button;buttonReloadMockData_.GetIdealSize(&size_button);rect_control = CRect(CPoint(rect_control.left,rect_control.bottom+10),size_button);buttonReloadMockData_.MoveWindow(rect_control);CSize size_button4;buttonReloadMockData10_.GetIdealSize(&size_button4);rect_control = CRect(CPoint(rect_control.right+10, rect_control.top), size_button);buttonReloadMockData10_.MoveWindow(rect_control);CSize sizeButton2;buttonReloadListView_.GetIdealSize(&sizeButton2);rect_control = CRect(CPoint(rect_control.right+10,rect_control.top),sizeButton2);buttonReloadListView_.MoveWindow(rect_control);}

图2
在这里插入图片描述
图3
在这里插入图片描述

项目下载地址

https://download.csdn.net/download/infoworld/89036594

参考

  1. GetScrollBarInfo 函数 (winuser.h) - Win32 apps | Microsoft Learn

  2. SCROLLBARINFO (winuser.h) - Win32 apps | Microsoft Learn

  3. ShowScrollBar 函数 (winuser.h) - Win32 apps | Microsoft Learn

相关文章:

[WTL/Win32]_[初级]_[如何设置ListView的列宽不出现水平滚动条]

场景 开发WTL/Win32的程序时&#xff0c;经常会用到表格控件CListViewCtrl。这个控件需要设置列的宽度&#xff0c;当用完100%的宽度来平均分配给列宽时&#xff0c;一加载数据多&#xff0c;就会出现垂直滚动条后&#xff0c;水平滚动条也会同时出现的问题。怎么设置才能让水…...

Mac更换JDK版本

1.确保系统中存在多个Java版本。 在Terminal中执行&#xff1a; /usr/libexec/java_home -V 结果&#xff1a; Matching Java Virtual Machines (2): 11.0.1, x86_64: "Java SE 11.0.1" /Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home 1.8.0_2…...

Day55:WEB攻防-XSS跨站CSP策略HttpOnly属性Filter过滤器标签闭合事件触发

目录 XSS跨站-安全防御-CSP XSS跨站-安全防御-HttpOnly XSS跨站-安全防御-XSSFilter(过滤器的意思) 1、无任何过滤 2、实体化 输入框没有 3、全部实体化 利用标签事件 单引号闭合 4、全部实体化 利用标签事件 双引号闭合 5、事件关键字过滤 利用其他标签调用 双引号闭合…...

root_fs文件系统结构分析和内核加载流程

目录 概述 1 根文件系统下目录介绍 2 文件系统内容分析 2.1 etc/inittab代码分析 2.2 /etc/init.d/rcS 代码分析 2.3 /etc/mdev.conf代码分析 2.3.1 功能概述 2.3.2 /etc/mdev.conf的详细代码 2.4 /etc/init.d/rcS的源代码文件 3 分析内核中加载root_fs的流程 3.1 调…...

macOS系统配置RUST开发环境

打开rust语言官方网,然后点击马上开始: Rust 程序设计语言 配置RUST开发环境: 使用curl下载rust安装脚本: 复制到终端执行: curl --proto =https --tlsv1.2 -sSf https://sh.rustup.rs | sh 输入: y 选择默认安装,输入: 1...

Android 15全面解读:性能飙升、隐私守护与智能生活新纪元

1. 更强大的性能 Android 15 带来了一系列性能方面的改进&#xff0c;以确保您的设备在运行应用程序时能够更加流畅。通过对系统进行优化&#xff0c;Android 15 在响应速度和性能方面都有了显著的提升。 这些优化包括&#xff1a; 新一代处理器支持&#xff1a; Android 15 …...

Java项目:80 springboot师生健康信息管理系统

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统的角色&#xff1a;管理员、宿管、学生 管理员管理宿管员&#xff0c;管理学生&#xff0c;修改密码&#xff0c;维护个人信息。 宿管员…...

云服务器配置 docker-spark

云服务器配置 docker-spark 1. 安装2. 启动3. 查看4. 验证5. 其他 1. 安装 我的服务器是腾讯云轻量应用服务器&#xff0c;2 核 2 G&#xff0c;已经内置了 docker&#xff0c; 配置大概如下&#xff1a; ubuntuVM-20-5-ubuntu --------------------- OS: Ubuntu 22.04 LTS x…...

Matlab之求直角坐标系下两直线的交点坐标

目的&#xff1a;在直角坐标系下&#xff0c;求两个直线的交点坐标 一、函数的参数说明 输入参数&#xff1a; PointA&#xff1a;直线A上的点坐标&#xff1b; AngleA&#xff1a;直线A的倾斜角&#xff0c;单位度&#xff1b; PointB&#xff1a;直线B上的点坐标&#xf…...

Python3:ModuleNotFoundError: No module named ‘elftools‘

问题背景 问题 ModuleNotFoundError: No module named ‘elftools’ 解决方法 pip3 install pyelftools 成功&#xff01;&#xff01;&#xff01;...

【Vue】创建vue项目 npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED

在安装完vue后&#xff0c;一段时间后发现再次使用出错&#xff1b;感觉可能是使用了代理的原因&#xff0c;但是就算关闭了代理一样不行&#xff1b;最后重启大法解决。 此处记录解决时使用到的命令。 检查版本 node -v cnpm -v vue --version vue -V安装 npm install -g vu…...

5、Cocos Creator 动作系统

目录 1、动作系统 API 2、动作系统 API 3、缓动动作 4、参考 动作系统并不能取代动画系统&#xff0c;动作系统提供的是面向程序员的 API 接口&#xff0c;而动画系统则是提供在编辑器中来设计的。它们服务于不同的使用场景&#xff0c;动作系统比较适合来制作简单的形变和…...

web3 token 如何理解

"Web3 Token"是指建立在Web3技术堆栈上的数字令牌。为了更好地理解这个概念&#xff0c;让我们逐步解释&#xff1a; Web3&#xff1a;指的是下一代互联网&#xff08;Web3.0&#xff09;&#xff0c;它是基于区块链技术的去中心化网络。Web3的核心理念是去中心化、安…...

unity pivot和center的区别

在Unity中&#xff0c;“pivot” 和 “center” 是两个在物体变换和编辑过程中经常提到的概念&#xff0c;它们表示物体的不同位置或者参考点。下面是它们的区别&#xff1a; Pivot&#xff08;中心点&#xff09;&#xff1a; Pivot 是物体的旋转和缩放的参考点。在 Unity 中&…...

Python学习笔记-简单案例实现多进程与多线程

Python 的多进程与多线程是并发编程的两种重要方式&#xff0c;用于提高程序的执行效率。它们各自有不同的特点和适用场景。 多进程&#xff08;Multiprocessing&#xff09; 概念&#xff1a; 多进程是指操作系统中同时运行多个程序实例&#xff0c;每个实例称为一个进程。…...

python常用的语法

Python是一种高级、通用、解释型的编程语言&#xff0c;具有简洁、易于阅读和理解的语法。以下是Python中常用的语法&#xff1a; 变量定义和赋值&#xff1a; variable value输出内容&#xff1a; print("Hello, World!")条件判断&#xff1a; if condition:# 条件…...

【计算机网络】概述

&#x1f4dd;本文介绍 本文为计算机网络的概述&#xff0c;会综合概述一下计算机网络 &#x1f44b;作者简介&#xff1a;一个正在积极探索的本科生 &#x1f4f1;联系方式&#xff1a;943641266(QQ) &#x1f6aa;Github地址&#xff1a;https://github.com/sankexilianhua &…...

【Flink connector】文件系统 SQL 连接器:实时写文件系统以及(kafka到hive)实战举例

文章目录 一. 滚动策略&#xff1a;sink后文件切分(暂不关注)1. 切分分区目录下的文件2. 小文件合并 二. 分区提交1. 分区提交触发器 &#xff08;什么时候创建分区&#xff09;1.1. 逻辑说明1.2. 举例说明 2. 分区时间提取器 (用于partition-time情况下partition commit策略)2…...

RpcContext :提供了在 RPC 调用过程中访问当前调用信息的方法

在 Dubbo 中&#xff0c;RpcContext 是一个上下文对象&#xff0c;它提供了在 RPC 调用过程中访问当前调用信息的方法。RpcContext.getClientAttachment() 方法用于获取客户端设置的附件&#xff08;Attachment&#xff09;信息。这些附件信息通常是在 RPC 调用发起方&#xff…...

机器学习 - 提高模型 (代码)

如果模型出现了 underfitting 问题&#xff0c;就得提高模型了。 Model improvement techniqueWhat does it do?Add more layersEach layer potentially increases the learning capabilities of the model with each layer being able to learn some kind of new pattern in…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...