MoreRSS

site iconSunZhongWei | 孙仲维 修改

博客名「大象笔记」,全干程序员一名,曾在金山,DNSPod,腾讯云,常驻烟台。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

SunZhongWei | 孙仲维 的 RSS 预览

Magento Shop By 过滤条件中禁用分类过滤

2025-08-02 12:55:16

简单的做法是在 Magento 后台全局样式里,把分类过滤部分的 HTML 代码隐藏。

首先在网站的 HTML 页面中,找到 Shop By 分类部分的 class 特征。 然后将这部分隐藏即可。例如:

.filter-options-item.filter-cat{
    display: none;
}

然后到 Magento 的后台,通过全局 CSS 样式来隐藏掉这部分的显示即可。参考:

Magento 添加全局 CSS 样式

根据不同的子 website 设置不同的 style, 即可区分隐藏或者显示规则。

尝试 qwen3 的 0.6b 模型

2025-08-01 20:35:08

之前尝试了 Google Gemma 3n 模型,参考笔记 Ollama 安装 Google Gemma 3n 模型。但是,我想找一个占用内存更小,更流畅的 LLM 模型。

恰好看到有人在讨论 qwen3 0.6b 模型,于是测试了一下,发现运行很流畅。

安装并运行

ollama run qwen3:0.6b

测试运行效果

很流畅,居然还带 thinking 过程。。。

模型文件大小

> ollama list

NAME              ID              SIZE      MODIFIED
qwen3:0.6b        7df6b6e09427    522 MB    4 hours ago
gemma3n:latest    15cb39fd9394    7.5 GB    2 weeks ago

相比 gemma3n 这个模型小多了,只有 500M。

内存和 CPU 占用

qwen3:0.6b 内存和 CPU 占用

占用内存 1.5G 内存左右。这个就非常完美了。

模型参数

>>> /show info
  Model
    architecture        qwen3
    parameters          751.63M
    context length      40960
    embedding length    1024
    quantization        Q4_K_M

Golang Walk 增加 Windows 应用图标

2025-07-31 17:15:45

用 Golang Walk 开发了一个 Windows GUI 应用程序,用于批量生成决赛证书。 基础功能已经完成。目前唯一的遗憾是应用程序没有图标。为了让这个应用程序看起来更专业,我决定为它添加一个图标。

先看最终效果:

显示效果

Golang Walk Windows 应用图标

重新生成 syso 文件

参考 Github 上的一个套路:

https://github.com/lxn/walk/issues/361

首先去 iconfont 网站下载一个免费的图标文件,然后将其转换为 ICO 格式。可以使用在线工具或软件来完成这个转换。

然后将生成的 ICO 文件放在项目目录下,例如 main.ico。

重新生成 syso 文件,使用以下命令:

rsrc -manifest main.manifest -ico main.ico -o rsrc.syso

其实就是在之前的基础上,增加了 -ico main.ico 参数。

修改 golang 代码

需要在代码中引用这个图标文件。可以在 main.go 文件中添加以下代码:

// number 2 is resource ID printed by RSRC.exe while making accounting.syso
var appIcon, _ = walk.NewIconFromResourceId(2)

func main() {
	var outTE *walk.TextEdit

	decl.MainWindow{
		Title:  "决赛证书批量生成工具",
		Icon:   appIcon, // 使用上面定义的图标
		Size:   decl.Size{Width: 600, Height: 400},
		Layout: decl.VBox{},
	// ...

如果不加 Icon: appIcon,则不会显示图标,只会看到文件目录里 exe 文件有了图标,但运行时窗口没有图标。

重新编译 exe 文件

go build -ldflags="-H windowsgui"

然后打开就可以看到图标了。

resource ID 问题

如果直接使用上面链接的里的 resource ID 3,可能会导致运行时错误:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x20 pc=0x7a511c]

然后我在另一个 issue 中找到了解决方案,就是替换 3 为 2:

Maybe you can try to change resource ID 3 to 2 if you are using akavel/rsrc v0.10

这也太抽象了,虽然确实可以解决问题,但我还是不太明白为什么。

然后有人推荐了 https://github.com/josephspurrier/goversioninfo 这个工具来解决。 有空再看看吧。

如何确定 syso 文件中的 icon 文件的 resource ID?

https://github.com/akavel/rsrc/issues/20

有人 fork 了一个版本,可以输出 icon 对应的 resource ID.

Golang Walk 通过 Goroutine 处理长时间运行的任务,避免界面卡死

2025-07-31 13:15:38

继续使用 Golang Walk 开发批量生成图片的 Windows 桌面客户端。 但是,要一次性生成几百张图片时,界面会卡死,无法响应用户操作。😅

哈哈,感觉非常像 Android 开发中的 ANR(Application Not Responding)问题。估计也是新开一个类似 kotlin 的协程来处理长时间运行的任务。 对于 Golang 来说就是使用 Goroutine 来处理长时间运行的任务。

ANR 问题

Golang Walk 对于长时间运行的任务,点击按钮后,如何保证界面不会卡死,而且能实时更新 textedit 中的内容呢?

解决方案:

  1. 使用 Goroutine:将长时间运行的任务放入 Goroutine 中执行,这样就不会阻塞主线程,从而避免界面卡死。

  2. 使用 Walk 的 Synchronize 方法:在 Goroutine 中更新 UI 时,必须使用 Walk 的 Synchronize 方法,以确保在主线程中执行 UI 更新操作。

  3. 定期更新进度:在长时间运行的任务中,可以定期更新进度信息到 textedit 中,以便用户了解当前进度。

以下是一个示例代码片段,演示如何在点击按钮后启动一个 Goroutine 来处理长时间运行的任务,并实时更新 UI:

go func() {
    // 在这里执行长时间运行的任务
    for i := 0; i < 100; i++ {
        time.Sleep(100 * time.Millisecond) // 模拟耗时操作
        outTextEdit.Synchronize(func() {
            outTextEdit.AppendText(fmt.Sprintf("当前进度: %d%%\r\n", i+1))
        })
    }
}()

这里 go 关键字用于启动一个新的 Goroutine。

Synchronize 方法的作用

Synchronize enqueues func f to be called some time later by the main goroutine from inside a message loop.

func (wb *WindowBase) Synchronize(f func()) {
	wb.group.Synchronize(f)

	win.PostMessage(wb.hWnd, syncMsgId, 0, 0)
}

Synchronize 方法的作用是将传入的函数 f 安排在主 Goroutine 中执行。这对于更新 UI 非常重要,因为 Walk 的 UI 元素只能在主 Goroutine 中安全地访问和修改。

这类似于 Android 开发中的 UI 线程的概念。

血泪教训,中文慎用思源字体,还是阿里的字体更靠谱

2025-07-30 13:48:21

之前用 Golang 开发了一个服务器端批量生成大赛获奖证书图片的功能。参考前文(Golang 批量生成获奖证书图片时的字体问题汇总) 然后,不出所料,上线后就被用户反馈有 Bug。哎,做个好人真难,干得越多,出 Bug 越多。

Bug 现象

  • 生成的证书图片,涉及到数字下标的一律不显示。例如二氧化碳的下标 2 就不见了,CO₂ 显示成 CO 😅
  • 有些字缺笔画。例如,飘逸的逸字,缺少了兔子的点。那个字我就不认识了。
  • 有些中文简体字显示成了繁体字

Bug 分析

第一个问题,我还能理解,可能字符支持的不全;但是第二个我就不能理解了。 后来,我看了一下思源字体的属性

思源字体的属性

可以看到,作者是日本人,这就解释了为什么有些字缺笔画,有些中文简体字显示成了繁体字。 因为作者不是中国人,所以对简体中文的校验和支持不够全面。

而且,这些外企搞的字体或者软件,早期都是中国台湾地区,或者日本做的测试,其实也看不出什么问题。

理论上,换成一个通用的简体中文字体就能解决。

更换字体

经同事设计大师的推荐,我决定使用阿里巴巴普惠体 3.0 版本的字体。可以免费从官方网站下载:

https://www.alibabafonts.com/#/font

也没有什么版权问题,直接下载使用就行了。

在 Golang 代码中,修改了字体文件后,运行测试,发现之前反馈的 Bug 都解决了。😄

又是惊心动魄的一天。

支持的字符数对比

修复这个 bug 之后,我就无心工作了。可能修复线上问题的精神压力过大,我就想看看不同字体支持的字符数对比,顺便放松一下心情。 于是,让 AI 写了一段 Python 代码,来统计不同字体文件中 cmap 表中的字符数,并打印出来,按照支持的字符数量多少排序。

import os
from fontTools.ttLib import TTFont

def get_supported_chars(font_path):
    try:
        font = TTFont(font_path)
        cmap = font['cmap']
        chars = set()
        for table in cmap.tables:
            chars.update(table.cmap.keys())
        return chars
    except Exception:
        return set()

def list_fonts_char_count(directory='.'):
    font_files = [f for f in os.listdir(directory) if f.lower().endswith(('.ttf', '.otf'))]
    font_char_counts = []
    for font_file in font_files:
        chars = get_supported_chars(os.path.join(directory, font_file))
        font_char_counts.append((font_file, len(chars)))
    font_char_counts.sort(key=lambda x: x[1], reverse=True)
    for font_file, count in font_char_counts:
        print(f"{count}: {font_file}")

if __name__ == "__main__":
    directory = os.path.dirname(__file__) or "."
    list_fonts_char_count(directory)

以下是运行结果:

44812: SourceHanSans-Medium.ttf  思源黑体
30847: SourceHanSerifCN-Bold.otf  思源宋体
30847: SourceHanSerifCN-ExtraLight.otf
30847: SourceHanSerifCN-Heavy.otf
30847: SourceHanSerifCN-Light.otf
30847: SourceHanSerifCN-Medium.otf
30847: SourceHanSerifCN-Regular.otf
30847: SourceHanSerifCN-SemiBold.otf
30789: NotoSansHans-Medium.otf
29197: AlibabaPuHuiTi-3-65-Medium.ttf  阿里巴巴字体

但是为何 AlibabaPuHuiTi-3-65-Medium.ttf 支持的字符最少,但是实际使用时,支持的中文字符确实最完整的呢?

原来字体文件中 cmap 表中的字符数只能反映字体声明支持的字符编码(即有字形的码位),但实际显示效果还受以下因素影响:

  • 合成字形(合字):有些字体通过合成、替换等方式支持更多字符,但 cmap 只统计基础码位。
  • 字体 fallback:操作系统或应用可能自动用其他字体补全缺失字形,导致实际显示比单一字体更完整。
  • 字体子集:有些字体文件只包含常用字符,但通过字体家族或外部机制补全。
  • 字体文件结构:部分字体可能将多个字符映射到同一个字形(glyph),但 cmap 只统计码位,不统计视觉效果。
  • 编码方式:部分字体可能支持某些字符的变体或扩展区,但 cmap 只统计标准区。

cmap 表只能反映“声明支持”的字符数,不能完全代表“实际可用的中文字符覆盖率”。 实际使用时,字体设计、系统渲染和应用 fallback 机制都会影响最终效果。

从阿里巴巴普惠体 3.0 的官网看,显示支持的汉字字符数 87887 个,远远大于 cmap 表中显示的 29197 个字符。

阿里巴巴普惠体支持的汉字字符数

字体文件大小对比

> ls -lah
total 124M
 8.1M Jul 29 17:21 AlibabaPuHuiTi-3-65-Medium.ttf*  阿里巴巴字体
 8.1M Jul 11  2014 NotoSansHans-Medium.otf*  思源黑体
  33M Dec  1  2020 SourceHanSans-Medium.ttf* 思源黑体
  12M Jul 25 15:56 SourceHanSerifCN-Bold.otf* 思源宋体
 9.9M Jul 25 15:56 SourceHanSerifCN-ExtraLight.otf*
  11M Jul 25 15:56 SourceHanSerifCN-Heavy.otf*
  11M Jul 25 15:56 SourceHanSerifCN-Light.otf*
  11M Jul 25 15:56 SourceHanSerifCN-Medium.otf*
  11M Jul 25 15:56 SourceHanSerifCN-Regular.otf*
  11M Jul 25 15:56 SourceHanSerifCN-SemiBold.otf*

总结

字体的选择很重要,尤其是中文字体。选择国内大厂的字体更靠谱。

Golang Walk 开发 Windows GUI 应用,Hello World 示例

2025-07-29 10:33:32

想开发一个简单的 Windows GUI 应用,实现证书图片的批量生成功能。

选择 Golang 开发 Windows GUI 的原因

尝试了一圈 WPF, React Native for Windows, 我感觉还是 Golang 开发更顺手一些。 不常写 C#,一段时间不写,语法就忘了。

而且这个证书图片的生成功能,我已经用 Golang Gin 实现了一套服务端的接口。 现在只需要把这部分代码移植到 Windows GUI 上就可以了。

使用 Golang Walk 库

也调研了其他的 Golang GUI 库:

  • Fyne:依赖较多,而且我运行不起来
  • Wails: WebView2 的方案,但我接受不了还有 Node JS 依赖
  • gtk3: 需要额外安装 gtk3 库

后来我转头一想,为何不能用 Golang 直接调用 Win32 API 呢?于是我找到了 Walk 库。

安装非常简单,立马就能运行起来,简单易上手。

下面演示一下如何实现一个 Hello World 的 GUI 应用。

Hello World 示例

参考,官方 github 上的示例代码,新建一个 main.go 文件:

package main

import (
	"strings"

	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
)

func main() {
	var inTE, outTE *walk.TextEdit

	MainWindow{
		Title:   "Hello World",
		MinSize: Size{600, 400},
		Layout:  VBox{},
		Children: []Widget{
			HSplitter{
				Children: []Widget{
					TextEdit{AssignTo: &inTE},
					TextEdit{AssignTo: &outTE, ReadOnly: true},
				},
			},
			PushButton{
				Text: "SCREAM",
				OnClicked: func() {
					outTE.SetText(strings.ToUpper(inTE.Text()))
				},
			},
		},
	}.Run()
}

初始化项目

go mod init go_gui_cert
go mod tidy

Manifest 文件

创建一个 main.manifest 文件,命名为 main.manifest,内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
        </dependentAssembly>
    </dependency>
    <application xmlns="urn:schemas-microsoft-com:asm.v3">
        <windowsSettings>
            <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
            <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True</dpiAware>
        </windowsSettings>
    </application>
</assembly>

因为 Walk 库使用了 Windows Common Controls 6.0,所以需要这个 Manifest 文件。

Common Controls(通用控件) 是微软 Windows 系统提供的一套标准化 GUI 组件库,包含了一系列常用的界面元素,用于简化 Windows 应用程序的开发,确保不同程序在界面风格和交互逻辑上保持一致性。

主要特点:

  • 标准化组件:提供了按钮、列表视图、树状视图、进度条、滑块、标签页、日期选择器等常见控件,开发者无需重复开发这些基础元素。
  • 系统级支持:作为 Windows 系统的一部分(主要通过 comctl32.dll 动态链接库实现),这些控件与系统深度集成,能自动适配 Windows 的视觉风格(如 XP、Vista、Win10/11 的主题)。
  • 版本演进:随着 Windows 系统更新,Common Controls 也在迭代,例如从早期的版本 1.0 到后来的版本 6.0(支持更现代的视觉样式)。

编译 manifest 文件

需要先安装 rsrc 工具:

rsrc - Tool for embedding binary resources in Go programs.

rsrc 是一个用于将二进制资源嵌入到 Go 程序中的工具。 它可以将资源文件(如图标、字符串表、版本信息等)转换为 Go 可用的格式,并生成相应的 Go 代码或二进制文件。

go install github.com/akavel/rsrc

编译:

rsrc -manifest main.manifest -o rsrc.syso

编译运行

go build -ldflags="-H windowsgui"

后面的参数是为了不显示 cmd 控制台窗口。编译速度非常快,秒完成。👍

这时候,就会看到生成了一个 exe 文件,双击运行就可以看到一个简单的 GUI 界面。

界面效果

Golang Walk Hello World 界面

项目目录结构

 305 Jul 29 08:45 go.mod
1.0K Jul 29 08:45 go.sum
7.3M Jul 29 10:12 go_gui_cert.exe
 553 Jul 29 10:12 main.go
 889 Jul 29 08:45 main.manifest
1.1K Jul 29 08:46 rsrc.syso

生成的 exe 文件大约 7.3M,文件大小完全可以接受。

换台电脑运行

把生成的 exe 文件拷贝到其他 Windows 电脑上运行,发现可以正常运行。

只需要一个 exe 文件即可,不需要额外的依赖。两个系统均是 Windows 11。

完美!