gtkmm4中程序运行后如何调整Gtk::Window的位置
在gtkmm4中调整Gtk::Window位置的解决方案
你提到的问题很典型——GTK4对窗口管理API做了不少重构,原来gtkmm3里的move()和set_position(Gtk::WIN_POS_CENTER)确实被移除或调整了。下面我会给你两种可行的解决方案,一种是利用GTK4的内置对齐实现居中,另一种是用你自己计算的坐标手动移动窗口。
方法一:利用内置对齐快速实现窗口居中
如果你只是想让窗口居中显示,完全不用自己计算坐标,通过设置窗口的对齐属性就能轻松实现:
#include <gtkmm.h> class MyWindow : public Gtk::Window { public: MyWindow() { // 设置窗口默认大小 set_default_size(400, 300); // 设置水平和垂直方向居中对齐 set_halign(Gtk::Align::CENTER); set_valign(Gtk::Align::CENTER); } }; int main(int argc, char* argv[]) { auto app = Gtk::Application::create("org.example.CenteredWindow"); return app->make_window_and_run<MyWindow>(argc, argv); }
这种方式的好处是简洁,而且GTK会自动适配不同的显示系统(比如X11、Wayland),不需要你处理显示器几何信息的细节。
方法二:使用自定义坐标手动移动窗口
如果你需要用自己计算的坐标来控制窗口位置,就得借助Gdk::Surface的API了——GTK4把窗口位置的底层操作移到了Gdk::Surface层。需要注意的是,必须在窗口被映射(也就是显示出来)之后才能调用移动方法,所以我们通常会在signal_map()回调里执行这个操作。
结合你写的计算代码,完整的实现如下:
#include <gtkmm.h> class MyWindow : public Gtk::Window { public: MyWindow() { set_default_size(400, 300); // 连接窗口映射信号,窗口显示时触发回调 signal_map().connect(sigc::mem_fun(*this, &MyWindow::on_window_mapped)); } private: void on_window_mapped() { // 获取默认显示对象 Glib::RefPtr<Gdk::Display> display = Gdk::Display::get_default(); if (!display) return; Gdk::Rectangle monitor_geo; // 获取第一个显示器的几何信息 Glib::RefPtr<Gio::ListModel> monitors = display->get_monitors(); if (monitors->get_n_items() > 0) { Glib::RefPtr<Gdk::Monitor> monitor = std::dynamic_pointer_cast<Gdk::Monitor>(monitors->get_object(0)); if (monitor) { monitor->get_geometry(monitor_geo); } } // 获取窗口当前大小 int win_width, win_height; get_default_size(win_width, win_height); // 计算居中坐标 int pos_x = monitor_geo.get_width() / 2 - win_width / 2; int pos_y = monitor_geo.get_height() / 2 - win_height / 2; // 获取窗口对应的Surface并执行移动 Glib::RefPtr<Gdk::Surface> surface = get_surface(); if (surface) { surface->move(pos_x, pos_y); } } }; int main(int argc, char* argv[]) { auto app = Gtk::Application::create("org.example.CustomPosWindow"); return app->make_window_and_run<MyWindow>(argc, argv); }
关键说明:
signal_map():这个信号会在窗口第一次被显示到屏幕上时触发,此时窗口的Gdk::Surface已经初始化完成,调用move()才会生效。Gdk::Surface::move():这是GTK4中用来移动窗口的底层方法,替代了原来gtkmm3里的Gtk::Window::move()。- 多显示器场景:如果你需要针对当前窗口所在的显示器计算坐标,可以用
display->get_monitor_at_surface(surface)来获取窗口当前的显示器,而不是直接取第一个显示器。
内容的提问来源于stack exchange,提问作者YUKI N
相关产品推荐
相关产品推荐

