如何用Rust创建带菜单栏与按钮的GTK应用?代码问题排查
问题解决:GTK Rust 出现两个窗口的原因及修复
你的代码出现两个窗口的核心原因是同时手动创建了ApplicationWindow,又调用了app.set_child——后者会触发GTK自动生成一个新的应用主窗口来承载按钮,加上你手动创建的窗口,就导致了双窗口问题。
修复方案
不需要调用app.set_child,所有控件都应该放到你手动创建的ApplicationWindow中。另外GTK4中要显示菜单栏,需要将抽象的gio::Menu模型转换为可渲染的gtk::MenuBar控件,通常结合HeaderBar放置在窗口顶部。
修改后的完整代码:
use gtk::prelude::*; fn main() { let app = gtk::Application::new(Some("com.example.MyApp"), Default::default()); app.connect_activate(|app| { // 创建自定义主窗口 let window = gtk::ApplicationWindow::new(app); window.set_title("First GTK Program"); window.set_default_size(300, 200); // 创建按钮并绑定点击事件 let button = gtk::Button::with_label("Click me!"); button.connect_clicked(|_| println!("Button clicked!")); // 构建菜单模型 let file_menu = { let about_item = gio::MenuItem::new(Some("About"), Some("app.about")); let quit_item = gio::MenuItem::new(Some("Quit"), Some("app.quit")); let menu = gio::Menu::new(); menu.append_item(&about_item); menu.append_item(&quit_item); menu }; let menubar = gio::Menu::new(); menubar.append_submenu(Some("File"), &file_menu); // 创建HeaderBar承载菜单栏 let header_bar = gtk::HeaderBar::new(); header_bar.set_show_title_buttons(true); // 将菜单模型转为可显示的MenuBar控件 let menu_bar = gtk::MenuBar::from_gmenu(&menubar); header_bar.pack_start(&menu_bar); // 关联标题栏和主窗口 window.set_titlebar(Some(&header_bar)); // 将按钮设置为主窗口的子控件 window.set_child(Some(&button)); // 显示窗口 window.show(); }); // 注册菜单动作的快捷键和处理逻辑 app.set_accels_for_action("app.quit", &["<Ctrl>Q"]); app.connect_action_about(|_, _| { let about_dialog = gtk::AboutDialog::new(); about_dialog.set_program_name("First GTK Program"); about_dialog.set_version("1.0"); about_dialog.set_authors(&["Your Name"]); about_dialog.run(); about_dialog.close(); }); app.connect_action_quit(|app, _| app.quit()); app.run(); }
关键说明
- 窗口与控件的归属:所有可视化控件都应该挂载到你手动创建的
ApplicationWindow上,通过window.set_child设置,避免调用app.set_child触发自动窗口生成。 - 菜单栏的显示:
gio::Menu是菜单的数据模型,需要通过gtk::MenuBar::from_gmenu转换为可渲染的控件,结合HeaderBar可以让菜单栏自然融入窗口标题栏区域。 - 布局的选择:单个按钮不需要用
hbox,直接设置为窗口子控件即可;如果后续需要多个控件并排/堆叠,再考虑用Box、Grid等布局容器。
内容的提问来源于stack exchange,提问作者Evil Dragon
相关产品推荐
相关产品推荐

