You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用gtkmm 3.24连接XML控件到函数时,get_widget调用报错如何解决?

gtkmm 3.24编译错误:无法匹配Gtk::Builder::get_widget函数调用

问题背景

我正在学习C++及gtkmm 3.24的使用,已创建包含少量控件的简单窗口,但编译时出现错误,无法将控件事件连接到处理函数。以下是我的最小复现代码:

myWindow.h

#pragma once

#include <gtkmm/window.h>
#include <gtkmm/builder.h>
#include <gtkmm/button.h>

class MainWindow : public Gtk::Window
{
  public:
    MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& p_builder);

  protected:
    Glib::RefPtr<Gtk::Builder> m_builder;
    Glib::RefPtr<Gtk::Button> m_button;

    // Signal handler:
    void on_button_clicked();
};

myWindow.cpp

#include "myWindow.h"

#include <gtkmm/builder.h>
#include <gtkmm/button.h>
#include <iostream>

MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& p_builder)
: Gtk::Window(cobject)
{
    this->m_builder = p_builder;

    Glib::RefPtr<Gtk::Button> p_button;
    p_builder->get_widget("button1", p_button);

    this->m_button = p_button;
    m_button->signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_button_clicked) );
}

void MainWindow::on_button_clicked()
{
    std::cout << "The Button was clicked." << std::endl;
}

main.cpp

#include <iostream>
#include <cstring>

#include <gtkmm/application.h>
#include <gtkmm/builder.h>

#include "myWindow.h"

int main(int argc, char** argv)
{
    auto app = Gtk::Application::create(argc, argv);
    auto builder = Gtk::Builder::create_from_file("builder.ui");

    MainWindow* window = nullptr;
    builder->get_widget_derived("mainWindow", window);

    app->run(*window);
    return 0;
}

builder.ui

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <object id="mainWindow" class="GtkWindow">
    <property name="title">Pippo</property>
    <property name="default_width">400</property>
    <property name="default_height">300</property>
    <child>
     <object class="GtkGrid" id="grid">
      <property name="visible">True</property>
        <child>
          <object id="button1" class="GtkButton">
            <property name="label">Button 1</property>
            <property name="visible">True</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">0</property>
          </packing>
        </child>
     </object>
    </child>
  </object>
</interface>

编译错误信息

myWindow.cpp:18:26: error: no matching function for call to ‘Gtk::Builder::get_widget(const char [8], Glib::RefPtr<Gtk::Button>&)’
   18 |     p_builder->get_widget("button1", p_button);

错误原因及修复方案

错误原因

Gtk::Builder::get_widget()的第二个参数要求传入原始指针(raw pointer),但你传递的是Glib::RefPtr<Gtk::Button>类型变量,参数类型不匹配导致编译失败。

修复方案

有两种可行的修复方式:

方式1:改用原始指针获取控件

  1. 修改myWindow.h中的成员变量类型:
// 将原有的Glib::RefPtr<Gtk::Button> m_button;替换为:
Gtk::Button* m_button;
  1. 修改myWindow.cpp中的控件获取逻辑:
MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& p_builder)
: Gtk::Window(cobject)
{
    this->m_builder = p_builder;

    // 用原始指针接收控件
    Gtk::Button* p_button = nullptr;
    p_builder->get_widget("button1", p_button);

    this->m_button = p_button;
    m_button->signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::on_button_clicked) );
}

方式2:使用get_ref_ptr()获取RefPtr类型控件

如果你偏好使用Glib::RefPtr,可以直接调用Gtk::Builder::get_ref_ptr()方法(gtkmm 3.22及以上版本支持),替换原有的get_widget调用:

// 删除临时变量p_button,直接获取RefPtr
this->m_button = p_builder->get_ref_ptr<Gtk::Button>("button1");

额外注意事项

  • 确保builder.ui中的控件ID(button1)与代码中调用的名称完全一致,ID区分大小写。
  • 使用原始指针时,无需手动释放内存,Gtk::Builder会管理所有通过它创建的控件的生命周期,只要Builder对象未被销毁,控件就会保持有效。

内容的提问来源于stack exchange,提问作者Fabio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 05:22:16