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

如何修改CheckMenuItem的激活状态且不触发其激活信号?

解决CheckMenuItem编程修改状态时触发回调的问题

核心方案

在通过代码调用set_active修改勾选状态前,先阻塞回调信号,修改完成后再解除阻塞,避免触发不必要的逻辑。

修改后的代码

use gtk::prelude::*;
use appindicator3::prelude::*;
use appindicator3::{Indicator, IndicatorStatus, IndicatorCategory};

fn try_activate() -> bool {
    false
}

fn main() {
    gtk::init().unwrap();

    let indicator = Indicator::builder("aaa")
        .category(IndicatorCategory::ApplicationStatus)
        .icon("computer-symbolic", "icon")
        .status(IndicatorStatus::Active)
        .build();

    let m = gtk::Menu::new();

    let mi_enabled = gtk::CheckMenuItem::with_label("Active");
    m.append(&mi_enabled);

    // 保存回调句柄,用于后续阻塞/解除阻塞
    let handler_id = mi_enabled.connect_activate(|mi| {
        if mi.is_active() {
            println!("activating");
            if try_activate() {
                println!("activated successfully");
            } else {
                println!("failed to activate");
                // 先阻塞回调信号,再修改状态
                mi.block_signal(&handler_id);
                mi.set_active(false);
                mi.unblock_signal(&handler_id);
            }
        } else {
            println!("deactivating");
            println!("deactivated successfully");
        }
    });

    indicator.set_menu(Some(&m));
    indicator.set_secondary_activate_target(Some(&mi_enabled));

    gtk::main();
}

代码说明

  • 调用connect_activate时会返回一个SignalHandlerId,保存该ID用于后续信号控制
  • 当需要编程修改勾选状态时,先用block_signal阻塞回调信号,修改完成后用unblock_signal解除阻塞
  • 此方式能精准避免手动修改状态时触发回调逻辑,不会误执行停止服务的代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 11:27:04