You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AwesomeWM中创建基于imagebox的动态电池组件(Vicious)

Awesome WM + Vicious:动态更新wibox.widget.imagebox电池图标问题

问题描述

正在探索Awesome WM与Vicious,希望基于wibox.widget.imagebox并借助vicious.widgets.bat创建电池组件,但遇到无法动态修改组件image属性的问题。

主题文件theme.lua中已配置好不同电量的电池图标(含充电状态):

local icons_dir = os.getenv("HOME") .. "/.config/awesome/deco/icons/"

...

theme.battery = {}
for i = 0, 10 do
    theme.battery[i] = icons_dir.."bat/b"..(i*10)..".svg"
end

theme.battery_charging = {}
for i = 0, 10 do
    theme.battery_charging[i] = icons_dir.."bat/b"..(i*10).."c.svg"
end

尝试以下两种方法均失败:

  1. 在Vicious回调函数中返回图标路径,仅当组件为wibox.widget.textbox时能正确显示路径,作为imagebox则无效:
mybat = wibox.widget.imagebox()
vicious.register(mybat, vicious.widgets.bat,
                 function (widget, args)
                     if args[1] == "+" then
                         return beautiful.battery_charging[((args[2] + 5) - (args[2] + 5) % 10) / 10]
                     else
                         return beautiful.battery[((args[2] + 5) - (args[2] + 5) % 10) / 10]
                     end
                 end, 30, "BAT0")
  1. 直接在回调中设置widget.image属性,组件仍为空:
mybat = wibox.widget.imagebox()
vicious.register(mybat, vicious.widgets.bat,
                 function (widget, args)
                     if args[1] == "+" then
                         widget.image = beautiful.battery_charging[((args[2] + 5) - (args[2] + 5) % 10) / 10]
                     else
                         widget.image = beautiful.battery[((args[2] + 5) - (args[2] + 5) % 10) / 10]
                     end
                 end, 30, "BAT0")

解决方案

问题核心是:设置image属性后,没有通知Awesome WM重绘组件。Vicious默认仅针对textbox的text属性做自动更新,对于imagebox需要手动触发重绘信号。同时优化电量索引计算方式,避免浮点数索引问题。

修改后的代码如下:

mybat = wibox.widget.imagebox()
vicious.register(mybat, vicious.widgets.bat,
                 function (widget, args)
                     -- 计算电量对应的索引(0-10),用整数除法避免浮点数
                     local bat_idx = math.floor((args[2] + 5) / 10)
                     -- 限制索引范围,防止越界报错
                     bat_idx = math.clamp(bat_idx, 0, 10)
                     
                     if args[1] == "+" then
                         widget.image = beautiful.battery_charging[bat_idx]
                     else
                         widget.image = beautiful.battery[bat_idx]
                     end
                     -- 发送信号通知组件重绘和布局更新
                     widget:emit_signal("widget::redraw_needed")
                     widget:emit_signal("widget::layout_changed")
                 end, 30, "BAT0")

关键说明

  • math.clamp是Awesome WM内置工具函数,用于将数值限制在0-10范围内,避免电量计算异常导致索引越界
  • 必须调用widget::redraw_needed信号:即使修改了image属性,界面也不会自动更新,需要主动通知WM重绘组件
  • widget::layout_changed信号可选:若图标尺寸变化时布局需要调整,可添加该信号确保界面布局正确

内容的提问来源于stack exchange,提问作者Andrey Voeyko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:45:36