访问部件
要访问部件,例如show()一个对话框,请使用get_widget()方法,并向其提供一个部件名。这个名称应该在Glade的窗口属性中指定。如果找不到该部件或是部件的类型不对,则指针将被设为nullptr。
auto pDialog = builder->get_widget<Gtk::Dialog>("DialogBasic");
Gtk::Builder会进行空指针和部件类型检查,并在命令行上显示相关的警告。
请注意,你并没有使用get_widget()实例化部件,你只是获得了指向已经存在的部件的指针。当你在同一个Gtk::Builder上用同一个名称调用get_widget()你总是会得到指向同一实例的指针。部件在函数Gtk::Builder::create_from_file()执行期间被实例化。
get_widget()返回一个经manage()处理的子部件(参阅内存管理章节),因此在删除其父部件时它们将被一并删除。无法管理Windows(例如Dialogs)因为它们没有父容器,所以你必须在某个时候删除它们。Gtk::Builder的文档中有更多关于对不同类型的对象如何进行内存管理的介绍。
- 24.2.1. 示例
24.2.1. 示例
这个简单示例展示了如何在运行时加载Glade文件并使用Gtk::Builder访问部件。
File: main.cc (For use with gtkmm 4)
#include <gtkmm.h> #include <iostream> namespace { Gtk::Dialog* pDialog = nullptr; Glib::RefPtr<Gtk::Application> app; void on_button_clicked() { if (pDialog) pDialog->hide(); //hide() will cause Gtk::Application::run() to end. } void on_app_activate() { // Load the GtkBuilder file and instantiate its widgets: auto refBuilder = Gtk::Builder::create(); try { refBuilder->add_from_file("basic.glade"); } catch(const Glib::FileError& ex) { std::cerr << "FileError: " << ex.what() << std::endl; return; } catch(const Glib::MarkupError& ex) { std::cerr << "MarkupError: " << ex.what() << std::endl; return; } catch(const Gtk::BuilderError& ex) { std::cerr << "BuilderError: " << ex.what() << std::endl; return; } // Get the GtkBuilder-instantiated dialog: pDialog = refBuilder->get_widget<Gtk::Dialog>("DialogBasic"); if (!pDialog) { std::cerr << "Could not get the dialog" << std::endl; return; } // Get the GtkBuilder-instantiated button, and connect a signal handler: auto pButton = refBuilder->get_widget<Gtk::Button>("quit_button"); if (pButton) pButton->signal_clicked().connect([] () { on_button_clicked(); }); // It's not possible to delete widgets after app->run() has returned. // Delete the dialog with its child widgets before app->run() returns. pDialog->signal_hide().connect([] () { delete pDialog; }); app->add_window(*pDialog); pDialog->show(); } } // anonymous namespace int main(int argc, char** argv) { app = Gtk::Application::create("org.gtkmm.example"); // Instantiate a dialog when the application has been activated. // This can only be done after the application has been registered. // It's possible to call app->register_application() explicitly, but // usually it's easier to let app->run() do it for you. app->signal_activate().connect([] () { on_app_activate(); }); return app->run(argc, argv); }