GTK4如何实现子窗口置顶并居中显示在父窗口上方
问题描述
我在使用GTK4(Rust绑定+libadwaita)开发时,希望创建一个与父窗口绑定的子窗口,使其能够像常见的关于对话框那样,始终置顶并居中显示在主窗口之上。但目前运行代码后得到的是两个相互独立的窗口,未达到预期效果,运行效果如下图所示:
问题复现代码
use adw::prelude::*; use adw::{Application, ApplicationWindow, HeaderBar, Window}; use gtk::gio::ApplicationFlags; use gtk::{Box, Label, Orientation}; fn main() { let app = Application::new(None, ApplicationFlags::FLAGS_NONE); app.connect_activate(|app| { let window = ApplicationWindow::builder() .application(app) .default_width(320) .default_height(200) .title("Hello, World!") .build(); let parent_box = Box::new(Orientation::Vertical, 0); window.set_content(Some(&parent_box)); parent_box.append( &HeaderBar::builder() .title_widget(&Label::new(Some("Gtk Demo"))) .build(), ); let child_window = Window::builder() .transient_for(&window) .default_width(180) .default_height(120) .build(); let child_box = Box::new(Orientation::Vertical, 0); child_window.set_content(Some(&child_box)); child_box.append( &HeaderBar::builder() .title_widget(&Label::new(Some("Gtk Demo"))) .build(), ); window.present(); child_window.present(); }); app.run(); }
运行环境
- 操作系统:Manjaro Linux x86_64
- 桌面环境:GNOME 42.1
- 窗口系统:X11
解决方法
只需要在构建子窗口时补充两个配置项即可实现预期效果:
- 开启模态属性,拦截父窗口的输入事件
- 设置窗口类型提示为对话框,告知窗口管理器这是附属弹窗,保证其始终置顶于父窗口、随父窗口同步最小化/关闭,且自动居中显示
修改后的子窗口构建代码如下:
// 注意引入gdk模块,部分版本需要手动添加 use gtk::gdk; let child_window = Window::builder() .transient_for(&window) .modal(true) // 开启模态属性 .window_type_hint(gdk::WindowTypeHint::Dialog) // 标记窗口为对话框类型 .default_width(180) .default_height(120) .build();
补充说明
- 仅配置
transient_for只会向窗口管理器声明两个窗口的归属关系,不会自动实现置顶、模态拦截、自动居中的效果 - 如果需要实现标准的关于对话框,直接使用libadwaita内置的
adw::AboutWindow即可,该组件已经预置了对话框的所有默认行为,不需要手动配置上述属性。
内容的提问来源于stack exchange,提问作者Lomírus
相关产品推荐
相关产品推荐

