KDE Plasma 6 Plasmoid:Repeater外Switch状态更新异常求助
解决KDE Plasma 6 Plasmoid开关状态不更新问题
问题描述
刚入门20天,正在开发一款KDE Plasma 6 Plasmoid,功能是通过动态生成的开关启动脚本/应用。目前开关能正常生成并执行脚本,但存在状态同步问题:
- 脚本以
exit 1结束时,开关保持true状态 - 脚本以
exit 0结束时,开关应该切换为false,但实际未生效
比如执行dolphin; exit 1,点击开关后变为true并启动Dolphin,关闭Dolphin后开关无法回到false状态,main.qml中Plasma5Support.DataSource里的状态更新代码无法改变开关状态。
问题原因
- 原代码中
root.switches是只读JS数组,从JSON解析而来,修改其中对象的checked属性不会触发UI更新,因为不是QML的可绑定属性 - Repeater使用普通JS数组作为model,对象属性变化无法通知UI刷新
- Switch的
checked绑定的是modelData.defaultPosition,不是实时运行状态,初始绑定后不会随状态变化更新 onNewData中存在未定义变量checked的错误逻辑,状态更新逻辑不准确
解决代码(修改后的main.qml)
import QtQuick import QtQuick.Layouts import QtQuick.Controls import org.kde.plasma.plasmoid import org.kde.plasma.core as PlasmaCore import org.kde.plasma.components as PlasmaComponents3 import org.kde.kirigami as Kirigami import org.kde.plasma.plasma5support as Plasma5Support PlasmoidItem { id: root // 用ListModel替代只读JS数组,支持属性变化通知UI ListModel { id: switchModel Component.onCompleted: { const switches = JSON.parse(Plasmoid.configuration.switches); switches.forEach(switchData => { append(switchData); }); } } Plasma5Support.DataSource { id: executable engine: "executable" connectedSources: [] onNewData: function(sourceName, data) { // 找到对应ID的开关项 const switchIndex = switchModel.findIndex(switchItem => switchItem.switchId === data.switchId); if (switchIndex !== -1) { // 根据脚本退出码更新checked状态 const newChecked = data['exit code'] === 0; switchModel.setProperty(switchIndex, "checked", newChecked); } disconnectSource(sourceName); } function exec(cmd, switchId) { // 把switchId作为附加参数传递,方便后续匹配 connectSource(cmd, { switchId: switchId }); } } function toggleAction(switchId, checked) { const switchIndex = switchModel.findIndex(switchItem => switchItem.switchId === switchId); if (switchIndex !== -1) { const switchItem = switchModel.get(switchIndex); // 先更新UI状态,再执行对应脚本 switchModel.setProperty(switchIndex, "checked", checked); if (checked) { executable.exec(switchItem.onScript, switchId); } else { executable.exec(switchItem.offScript, switchId); } } } fullRepresentation: Item { Repeater { model: switchModel delegate: PlasmaComponents3.Switch { id: switchItem Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter // 绑定到model的checked属性,实时同步状态 checked: model.checked onToggled: { root.toggleAction(model.switchId, checked); } } } } }
关键修改说明
- 替换只读JS数组为
ListModel,让属性变化能自动通知UI刷新 - 调整
executable.exec方法,传递switchId作为附加参数,确保onNewData能准确匹配对应开关 - 将Switch的
checked属性绑定到model.checked,实现状态实时同步 - 修复
onNewData中的错误逻辑,通过findIndex精准定位开关项并更新状态 - 修改
toggleAction逻辑,先更新model状态再执行脚本,保证UI与操作一致
内容的提问来源于stack exchange,提问作者xkain
相关产品推荐
相关产品推荐

