使用Glade与Gtk::Builder在GTK3.0中连接信号至处理器报错求助
问题解决:Gtkmm按钮信号连接报错
错误原因
你用builder->get_object("start")获取的是Glib::Object基类对象,这个基类并没有clicked信号相关的成员。必须将其转换为具体的控件类型(比如Gtk::Button)才能调用对应的信号方法。另外你代码里的信号写法也有误,正确的信号调用是signal_clicked(),不是signal.clicked()。
修复方案
方案1:直接用get_widget获取控件指针
get_widget可以直接返回对应类型的控件指针,无需手动转型:
void Startup::startup() { auto app = Gtk::Application::create("org.gtkmm.geoquiz"); Gtk::Window* startWindow = nullptr; auto builder = Gtk::Builder::create(); builder->add_from_file("StartDialog.glade"); builder->get_widget("StartDialog", startWindow); Gtk::Button* start = nullptr; // 直接获取Button类型指针 builder->get_widget("start", start); if (start) { // 检查指针是否有效,避免空指针崩溃 // 正确调用signal_clicked(),并连接处理器 start->signal_clicked().connect(sigc::ptr_fun(&Startup::capitalSetHandler)); } app->run(*startWindow); }
方案2:使用cast_dynamic转型Glib::Object
如果必须用get_object,可以通过Glib::RefPtr的cast_dynamic方法向下转型:
void Startup::startup() { auto app = Gtk::Application::create("org.gtkmm.geoquiz"); Gtk::Window* startWindow = nullptr; auto builder = Gtk::Builder::create(); builder->add_from_file("StartDialog.glade"); builder->get_widget("StartDialog", startWindow); auto start_obj = builder->get_object("start"); // 转型为Gtk::Button的智能指针 auto start = Glib::RefPtr<Gtk::Button>::cast_dynamic(start_obj); if (start) { start->signal_clicked().connect(sigc::ptr_fun(&Startup::capitalSetHandler)); } app->run(*startWindow); }
额外注意事项
- 确保Glade文件中控件的ID是
start,且控件类型为GtkButton(对应Gtkmm的Gtk::Button),如果是Switch或ToggleButton,要替换为对应类型(Gtk::Switch、Gtk::ToggleButton)。 - 如果
capitalSetHandler是Startup类的非静态成员函数,需要用sigc::mem_fun替代sigc::ptr_fun:start->signal_clicked().connect(sigc::mem_fun(*this, &Startup::capitalSetHandler)); - 信号处理器的签名必须匹配对应信号的要求:比如
clicked信号的处理器需要是无参数、返回值为void的函数。
内容的提问来源于stack exchange,提问作者Anon35233
相关产品推荐
相关产品推荐

