ARTICLE · 1114354
龙芯电脑下的桌面时钟编译、安装教程
国庆快乐,昨天去上海博物馆看了中美洲展,今天回来继续
一、缘起
深度论坛上有一位作者用 PyQt5 写了一个桌面时钟日历挂件:大号数字时钟 + 农历 + 二十四节气 + 黄历宜忌 + 倒计时 + 番茄钟。作者的发布说明里写得很直白——嫌系统右下角的时间显示太小,就自己动手做了一个;并且明确表示"各位要是觉得需要增加功能的可以自行下载源码更改"。
原作者发布的 2.0 版压缩包里有一个 58MB 的"绿色单文件版",双击即用、不装依赖。但它是由 PyInstaller 在 x86_64 上打包的 ELF 程序,在龙芯电脑上根本无法运行:
$ file 桌面时钟 桌面时钟: ELF 64-bit LSB executable, x86-64 ... interpreter /lib64/ld-linux-x86-64.so.2跨架构没有捷径,只能走源码这条路。好在它是纯 Python 程序,适配成本远低于 C/C++ 程序。本文记录在龙芯 3A6000 + Loongnix 25 上把它跑起来、打成原生单文件、并配置开机自启的全过程。
特别说明:本软件的版权归原作者所有。本文仅记录在龙芯平台上运行它所需的适配改动,不改动原作者署名、不改变版权归属,也不用于任何商业用途。原帖地址见文末参考文献。
二、环境准备
2.1 本文验证环境
2.2 依赖检查
程序只依赖两个库,其中 PyQt5 是重量级依赖,zhdate 是农历计算库。
python3 -c "import PyQt5; print('PyQt5 OK')" python3 -c "from zhdate import ZhDate; print('zhdate OK')"如果 PyQt5 缺失,优先用系统包安装——发行版已经为龙芯编译好了原生 Qt5,比自行编译可靠得多:
sudo apt install python3-pyqt5zhdate 是纯 Python 包,直接用 pip 安装即可。Debian 12 及以后的系统受 PEP 668 保护,系统 Python 环境需要显式放行(或者自行创建虚拟环境):
pip3 install --user --break-system-packages zhdate提示:程序中"全局快捷键"依赖 keyboard库,而该库在 Linux 下需要在 root 权限下才能注册全局热键,普通用户下会静默失效。程序对此做了容错(找不到库也能正常启动),因此不必安装,用托盘图标或窗口内快捷键即可。
2.3 源码获取
从原帖提供的网盘地址下载 2.0 版压缩包(内含 shizhong.py 源码、桌面时钟.spec 打包配置、发布说明和 x86_64 绿色版),解压:
7z x 时钟.7z -o时钟 cd 时钟 ls # 发布说明.txt 桌面时钟 桌面时钟.spec shizhong.py三、源码适配
原作者的设计基线是"96 DPI 下的观感",并没有针对龙芯或 1080p 屏幕做验证。直接运行会暴露两个问题,另外还有一个只有打包后才会暴露的缺陷。以下改动共 4 处。
3.1 问题一:界面偏小(缩放系数)
2.0 版引入了全局缩放系数 GLOBAL_BASE,实际缩放公式为:
实际显示尺寸 = GLOBAL_BASE × (logicalDPI / 96)本机 logicalDPI = 96,即缩放完全由 GLOBAL_BASE 决定。作者默认值 0.65 在 1080p 屏上偏小(窗口仅 416×715 像素),调到 0.85 观感更合适。
# 原作 GLOBAL_BASE = 0.65# 适配后 GLOBAL_BASE = 0.853.2 问题二:底部被裁切(窗口高度小于内容高度)
这是原作的一个隐藏缺陷:窗口被写死为 640×1100,但布局的真实最小高度更大,导致最底部的倒计时一行被裁掉。用下面的脚本可以在不改动源码的情况下实测出来:
QT_QPA_PLATFORM=offscreen python3 - <<'PY' src = open('shizhong.py', encoding='utf-8').read() g = {'__name__': 'notmain'} # 不触发 __main__,便于只构造控件 exec(compile(src, 'shizhong', 'exec'), g) from PyQt5.QtWidgets import QApplication app = QApplication([]) w = g['ClockCalendarWidget']() print('窗口固定高度 =', w.height()) print('内容最小高度 =', w.minimumSizeHint().height()) PY原作实测结果:
窗口固定高度 = 1100 内容最小高度 = 1170 # 超出 70 像素,底部必被裁切由于所有尺寸都乘以同一个缩放系数,这个 70 像素的差额在任何缩放下都存在(比例恒为 1.064)。修复方式是让窗口高度不小于内容真实高度:
# 原作 WINDOW_WIDTH = 640; WINDOW_HEIGHT = 1100 # 适配后(1170 为实测最小高度,另留少量余量以兼容不同字体度量) WINDOW_WIDTH = 640; WINDOW_HEIGHT = 11803.3 问题三:小屏适配(竖向收敛)
原作的 DPI 补偿只考虑横向观感,不考虑"窗口会不会超出屏幕"。补一段竖向收敛逻辑,保证在低分辨率屏幕上自动缩小而不是顶出屏幕:
scr = app.primaryScreen() ldpi = scr.logicalDotsPerInch() if scr else 96 _scale = GLOBAL_BASE * (ldpi / 96.0) # 竖向收敛:窗口高度不得超过屏幕可用高度(留 40px 边距) if scr: _avail_h = scr.availableGeometry().height() if _scale * WINDOW_HEIGHT > _avail_h - 40: _scale = (_avail_h - 40) / WINDOW_HEIGHT globals()['_SCALE'] = _scale3.4 问题四:打包后开机自启失效
原作的开机自启是写一个 XDG 自启动文件:
Exec=python3 {script}在脚本方式下这行没问题。但一旦用 PyInstaller 打包成单文件可执行程序,python3 后面就跟了一个 ELF 二进制,登录时会启动失败。修复方式是区分运行形态:
def _launch_cmd(): if getattr(sys, "frozen", False): # PyInstaller 打包后 return f'"{sys.executable}"' # sys.executable 即可执行文件自身 return f'python3 "{os.path.abspath(sys.argv[0])}"'3.5 适配后的运行效果

src="http://mmb!iz.qpic.cn/sz_mmbiz_png/CUQWWCxOKIXB1QxYILia4vI9ldKeicFXmPI8fLAe2wQw8OlN6ccpxFCu8TtTib7GNnokqt3f1NmkpGaCyGicnyWqFUC4WTphLdEKTTZS9aia9JyE/0?from=appmsg"
界面为 544×1003(1920×1080、缩放 0.85 时),底部"距离秋分还有 13 天"完整显示——这正是修复高度缺陷后带来的直接效果。
四、运行验证
源码方式直接运行:
cd 时钟/loong64 python3 shizhong.py启动时终端会打印一行 DPI 日志,便于确认缩放是否符合预期:
[DPI] logicalDPI=96.0, devicePixelRatio=1.000, GLOBAL_BASE=0.85, scale=0.850验收检查清单:
五、编译打包:生成龙芯原生单文件
原作者用 PyInstaller 生成了 x86_64 绿色版。那么龙芯上能不能照做?可以,但有一点必须注意:
PyPI 上没有 loongarch64 的 PyInstaller 预编译包, pip install pyinstaller只会拉到源码包(sdist)。同时,源码包里也只预置了 Windows / macOS 的 bootloader,龙芯的 bootloader 需要自己编译。
好消息是 PyInstaller 官方代码里已经内置了龙芯架构的识别逻辑(PyInstaller/_shared_with_waf.py 中的 loongarch 分支),bootloader 源码也在源码包里,自己编译即可。
5.1 完整编译步骤
# 1) 拉取源码包(不要加 --only-binary,龙芯没有 wheel) pip3 download --no-deps -d /tmp/pyi pyinstaller cd /tmp/pyi && tar xzf pyinstaller-6.22.2.tar.gz # 2) 编译龙芯 bootloader(依赖 gcc,本项目无需额外第三方开发库) cd pyinstaller-6.22.2/bootloader python3 ./waf all # 产物落在 PyInstaller/bootloader/ 下: # install .../PyInstaller/bootloader/Linux-64bit-loongarch/run # 3) 安装 PyInstaller(从本地目录安装,才会带上刚编译的 bootloader) pip3 install --user --break-system-packages /tmp/pyi/pyinstaller-6.22.2 python3 -c "import PyInstaller,os;print(os.listdir(os.path.join(os.path.dirname(PyInstaller.__file__),'bootloader')))" # ['Darwin-64bit', 'Linux-64bit-loongarch', 'Windows-64bit-intel', 'Windows-32bit-intel', 'images'] # 4) 打包(在源码目录执行) cd 时钟/loong64 python3 -m PyInstaller --onefile --name 桌面时钟 --noconfirm shizhong.py5.2 打包结果
$ ls -lh dist/ -rwxr-xr-x 1 huzhou huzhou 54M 9月10日 16:35 桌面时钟 $ file dist/桌面时钟 ELF 64-bit LSB executable, LoongArch, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-loongarch-lp64d.so.1产出 54MB 的原生 LoongArch 单文件可执行程序,与原作者 x86_64 绿色版的形态一致。整个过程在 3A6000 上约 45 秒完成,其中 bootloader 编译不到 1 秒。
5.3 两种运行方式对比
python3 shizhong.py | |||
dist/桌面时钟 |
六、安装:启动器与开机自启
6.1 添加应用启动器
新建 桌面时钟.desktop:
[Desktop Entry] Type=Application Name=桌面时钟 Comment=桌面时钟日历挂件(农历/节气/宜忌/倒计时/番茄钟) Exec=/home/用户/桌面时钟/dist/桌面时钟 Icon=office-calendar Terminal=false Categories=Utility;Clock;安装到应用菜单(也可直接拖到桌面):
mkdir -p ~/.local/share/applications cp 桌面时钟.desktop ~/.local/share/applications/ chmod +x ~/.local/share/applications/桌面时钟.desktop注意 Exec= 必须写绝对路径,并按自己的实际存放位置修改。
6.2 开机自启
程序自带该功能:右键窗口 →"开机自启"。它会在 ~/.config/autostart/ 下生成 clock-calendar.desktop,内容形如:
[Desktop Entry] Type=Application Name=Clock Calendar Exec=python3 "/home/用户/桌面时钟/loong64/shizhong.py" X-GNOME-Autostart-enabled=true使用单文件版本时,该行会自动变成可执行文件本身的路径(这一步依赖 3.4 节的修复)。取消勾选会同步删除该文件。
6.3 使用要点
提醒:窗口是无边框工具窗,不会出现在任务栏。若桌面环境的面板没有"系统托盘"插件,请不要使用"隐藏到托盘",否则窗口会无法唤回。
七、调参速查
缩放不合适时只需改一个常量(shizhong.py 顶部):
(表中尺寸按本文适配后的窗口常量 640×1180 计算;原作窗口为 640×1100,其默认 0.65 对应 416×715。)
窗口高度超过屏幕时,3.3 节的竖向收敛逻辑会自动缩小,不会顶出屏幕。
八、小结
原作者在 x86 平台上用几十行 PyQt5 解决了一个"系统时钟太小"的小问题,并且开放源码允许他人修改——这种分享方式本身就值得尊重。本文所做的工作,只是让这份作品在国产架构的桌面上也能正常显示,版权与功劳都属于原作者。
参考文献
1. 桌面时钟(原作者发布帖),深度论坛。[https://bbs.deepin.org.cn/post/301338](https://bbs.deepin.org.cn/post/301338)
2. PyInstaller 官方文档 — Building the bootloader。[https://pyinstaller.org/en/stable/bootloader-building.html](https://pyinstaller.org/en/stable/bootloader-building.html)
3. PEP 668 — Marking Python base environments as "externally managed"。[https://peps.python.org/pep-0668/](https://peps.python.org/pep-0668/)
4. freedesktop.org — Desktop Entry Specification(XDG Autostart)。[https://specifications.freedesktop.org/desktop-entry-spec/latest/](https://specifications.freedesktop.org/desktop-entry-spec/latest/)
软件版权归原作者所有;本文仅在原作者开源代码基础上做龙芯平台适配记录,未改变版权归属。