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

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里的状态更新代码无法改变开关状态。

问题原因

  1. 原代码中root.switches是只读JS数组,从JSON解析而来,修改其中对象的checked属性不会触发UI更新,因为不是QML的可绑定属性
  2. Repeater使用普通JS数组作为model,对象属性变化无法通知UI刷新
  3. Switch的checked绑定的是modelData.defaultPosition,不是实时运行状态,初始绑定后不会随状态变化更新
  4. 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);
                }
            }
        }
    }
}

关键修改说明

  1. 替换只读JS数组为ListModel,让属性变化能自动通知UI刷新
  2. 调整executable.exec方法,传递switchId作为附加参数,确保onNewData能准确匹配对应开关
  3. 将Switch的checked属性绑定到model.checked,实现状态实时同步
  4. 修复onNewData中的错误逻辑,通过findIndex精准定位开关项并更新状态
  5. 修改toggleAction逻辑,先更新model状态再执行脚本,保证UI与操作一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 08:46:51