如何修改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
相关产品推荐
相关产品推荐

