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

在Rust + GTK4中如何使用模板回调函数?

在Rust + GTK4中如何使用模板回调函数?

Hey there! Looks like you're trying to set up a callback for the close-request signal in your GTK4 template using Rust. Let me walk you through how to get this working properly.

First, let's recap your UI template snippet (cleaned up for clarity):

<template class="MainWindow" parent="GtkApplicationWindow">
  <property name="default-width">600</property>
  <property name="default-height">300</property>
  <property name="title">App</property>
  <signal name="close-request" handler="on_window_close" swapped="true"/>
</template>

Now, to link this on_window_close handler to your Rust code, you'll use gtk-rs bindings' derive macros. Here's a step-by-step implementation:

1. Set up your Cargo.toml

Make sure you have the gtk crate added (adjust the version to match your setup):

[dependencies]
gtk = { version = "0.8", features = ["v4_8", "gnome_42"] }

2. Implement the MainWindow with template callbacks

You'll need to define your window struct, link it to the UI template, and register the callback function:

use gtk::prelude::*;
use gtk::{glib, CompositeTemplate, Inhibit, TemplateChild};

// Link the struct to your UI template
#[derive(CompositeTemplate, Default)]
#[template(file = "main_window.ui")] // Path to your UI file relative to the binary
pub struct MainWindow {
    // Declare any UI elements you want to access here with #[TemplateChild]
    // Example: #[template_child] pub status_label: TemplateChild<gtk::Label>,
}

// Mark this impl block as containing template callbacks
#[template_callbacks]
impl MainWindow {
    // Constructor to create a new window instance
    pub fn new(app: &gtk::Application) -> Self {
        let window = glib::Object::builder()
            .property("application", app)
            .build::<Self>();
        window.init_template().expect("Failed to load UI template");
        window
    }

    // Your callback for the close-request signal
    #[template_callback]
    fn on_window_close(&self) -> Inhibit {
        // Add your custom logic here (e.g., save data, show confirmation dialog)
        println!("Window is about to close!");

        // Return Inhibit(false) to allow closing, Inhibit(true) to block it
        Inhibit(false)
    }
}

// Register your window type with GTK
glib::wrapper! {
    pub struct MainWindow(ObjectSubclass<imp::MainWindow>) 
        @extends gtk::ApplicationWindow, gtk::Window, gtk::Widget, 
        @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager;
}

// Implement the GTK subclass for MainWindow
mod imp {
    use super::*;
    use gtk::subclass::prelude::*;

    #[derive(Default, CompositeTemplate)]
    #[template(file = "main_window.ui")]
    pub struct MainWindow;

    #[glib::object_subclass]
    impl ObjectSubclass for MainWindow {
        const NAME: &'static str = "MainWindow";
        type Type = super::MainWindow;
        type ParentType = gtk::ApplicationWindow;

        fn class_init(klass: &mut Self::Class) {
            klass.bind_template();
            // Register all template callbacks with GTK
            klass.bind_template_callbacks();
        }

        fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
            obj.init_template();
        }
    }

    // Empty implementations required by GTK subclassing
    impl ObjectImpl for MainWindow {}
    impl WidgetImpl for MainWindow {}
    impl WindowImpl for MainWindow {}
    impl ApplicationWindowImpl for MainWindow {}
}

Key things to remember:

  • The #[template_callback] macro tells gtk-rs which functions map to your UI's signal handlers.
  • The callback signature must match the signal's requirements: close-request expects a function that returns an Inhibit value to control whether the window closes.
  • In the subclass's class_init method, klass.bind_template_callbacks() is critical to register your callbacks with GTK.
  • Double-check the path to your main_window.ui—it should be accessible relative to your compiled binary (you might need to copy it to your build directory or use a build script to include it).

That should get your callback working smoothly with your GTK4 template in Rust!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 13:49:34