PAYATHON 2026

Quickshell 电池组件始终显示 0%,如何让电量正常更新?

数据阿明

建议使用 Quickshell.Services.UPower,将显示文字绑定到电池对象的属性。Quickshell 会处理 UPower 数据读取和变化通知,组件中无需手动创建 D-Bus 接口。

原代码中的 0% 对应 percentage 的初始值,仅凭显示结果无法确定读取失败的具体原因。先检查 DBus.createInterface() 是否可用,再区分首次读取失败和后续更新失败。

为什么文字能显示,电量却停在 0%?

Text 可以正常绘制,但 Component.onCompleted 中的调用仍可能失败。如果初始化时出现 JavaScript 异常,或者 Get 回调没有执行,percentage 就会保留初始值 0。

给出的代码只导入了 QtQuick 和 Quickshell,没有展示 DBus 对象的来源。Quickshell 的核心模块文档没有列出通用的 DBus.createInterface() API,不能假定导入 Quickshell 后就能使用它。先查看运行日志,确认是否存在 DBus is not defined 或相关方法不可用的错误。如果 DBus 来自额外的自定义封装,应按该封装的接口检查调用方式。Quickshell 核心模块文档

原代码已经主动调用了一次 update(),因此除了检查 PropertiesChanged,也要确认首次读取是否成功。

使用 UPower 属性绑定

下面的写法适用于提供这些类型和属性的 Quickshell 安装。问题没有给出版本,如果导入失败,先核对本机安装及对应版本文档。

用以下代码替换原来的 Text 组件,移除手动 D-Bus 调用:

import QtQuick
import Quickshell.Services.UPower

Text {
    id: battery

    readonly property UPowerDevice powerDevice: UPower.displayDevice
    readonly property bool batteryReady: powerDevice.ready
    readonly property int percentage: batteryReady
        ? Math.round(powerDevice.percentage * 100)
        : 0
    readonly property bool charging: batteryReady
        && powerDevice.state === UPowerDeviceState.Charging

    font.family: "0xProto Nerd Font Mono"
    font.pixelSize: 12
    color: Theme.active

    text: batteryReady
        ? (charging ? " " : "") + percentage + "%"
        : "--"

    anchors.verticalCenter: parent.verticalCenter
}

UPower.displayDevice 是用于显示整体电源状态的聚合设备,适合状态栏电量组件。它不会为 null,但初始数据可能尚未就绪。通过 ready 决定是否显示电量,可以避免在等待数据时误显示 0%。UPower 文档

这些属性使用 QML 绑定。电池对象的电量或状态变化时,相关表达式会重新计算,更新 text。Quickshell 为这些属性提供变化通知。UPowerDevice 源码

示例沿用原配置的 Theme.active,前提是该主题对象在组件中可见。

注意两种接口的电量范围

直接通过 D-Bus 读取 UPower 的 Percentage,得到的是 0 到 100 的数值。因此,原代码对原始返回值使用 Math.round(v) 时,不需要再乘以 100。UPower Device 文档

Quickshell 的 UPowerDevice.percentage 使用 0 到 1 的比例值,其实现会将 D-Bus 数值乘以 0.01。所以上面的替换代码需要使用 Math.round(powerDevice.percentage * 100) 来显示百分数,不能把这一处理直接套用到原来的 D-Bus 回调上。Quickshell 电量转换实现

充电图标通过 UPowerDeviceState.Charging 判断电池是否正在充电。接通电源但已经充满或等待充电时,电池不一定处于该状态。UPowerDeviceState 文档

替换后仍不更新,如何继续定位?

先在终端检查 UPower 实际提供的数据:

upower --enumerate
upower --show-info /org/freedesktop/UPower/devices/battery_BAT0
upower --show-info /org/freedesktop/UPower/devices/DisplayDevice
upower --monitor-detail

这些命令分别用于列出设备、查看指定设备信息和持续观察设备变化。如果枚举结果中的电池路径不同,应使用实际路径。upower 命令文档

根据观察结果继续排查:

  • 命令行中的电量和状态正常变化,组件不变:检查 Quickshell 日志、模块导入和 QML 绑定错误。
  • 物理电池数据正常,DisplayDevice 数据异常:检查 UPower.devices 中的具体电池对象。DisplayDevice 是聚合设备,不等同于固定的 BAT0。
  • 命令行中的设备数据也不变化:继续排查 UPower 和底层电池数据上报。界面定时刷新无法修复数据源本身不更新的问题。

如果必须保留手动 D-Bus 方案,还需要确认封装连接的是 system bus。Quickshell 内置的 UPower 服务也使用该总线。随后检查 Get 的回调签名、返回值是否需要解包,以及信号订阅方式;这些细节取决于实际使用的 D-Bus 封装,现有材料不足以给出对应修复代码。Quickshell UPower 连接实现

备注:内容仅供参考。