rust 如何更改CheckMenuItem的活动状态而不触发其活动信号?

f4t66c6m  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(84)

我用libappindicator3创建了一个托盘图标,其中包含一个激活系统服务的CheckMenuItem
但是激活系统服务可能会失败,当它无法激活时,我也希望取消选中CheckMenuItem。但是,每当我运行set_active(status)时,它都会触发connect_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);

    mi_enabled.connect_activate(|mi_enabled| {
        if mi_enabled.is_active() {
            println!("activating");
            if try_activate() {
                println!("activated successfully");
            } else {
                println!("failed to activate");
                mi_enabled.set_active(false);
            }
        } else {
            println!("deactivating");
            println!("deactivated successfully");
        }
    });

    indicator.set_menu(Some(&m));

    indicator.set_secondary_activate_target(Some(&mi_enabled));

    gtk::main();
}

字符串
这是我尝试激活它时的输出:

activating
failed to activate
deactivating
deactivated successfully


我想要的是激活失败,设置_active(false)而不触发“停用”。
我认为这可以通过一个全局变量来解决,我可以在编程方式更改它时设置它,然后在信号处理程序中检查它。但这似乎是一条错误的道路。

aelbi1ox

aelbi1ox1#

我设法通过在set_active调用周围使用block_signalunblock_signal来解决这个问题。然而,由于我试图在闭包周围引用函数的返回值,所以我在它周围使用了Rc<RefCell<>>,这似乎过多,但我没有找到解决方法。
结果代码:

let handler_id: Rc<RefCell<Option<SignalHandlerId>>> = Rc::new(RefCell::new(None));

    let h_id = mi_enabled.connect_activate(glib::clone!(@strong handler_id => move |mi_enabled| {
        if mi_enabled.is_active() {
            println!("activating");
            if try_activate() {
                println!("activated successfully");
            } else {
                println!("failed to activate");
                mi_enabled.block_signal(&handler_id.as_ref().borrow_mut().as_mut().unwrap());
                mi_enabled.set_active(false);
                mi_enabled.unblock_signal(&handler_id.as_ref().borrow_mut().as_mut().unwrap());
            }
        } else {
            println!("deactivating");
            println!("deactivated successfully");
        }
    }));

    handler_id.as_ref().borrow_mut().insert(h_id);

字符串

相关问题