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

请求提供Gtkmm函数g_timeout_add的正确使用示例

解决Gtkmm中g_timeout_add调用类成员函数的问题

这个问题我之前也碰到过,核心原因是g_timeout_add作为GLib的C原生API,没法直接用C++类的非静态成员函数当回调——因为这类成员函数会自动携带一个隐含的this指针,和它要求的GSourceFunc函数签名完全不匹配,这就是你不管加不加&都会报错的根源。

下面给你两种可行的解决方案,优先推荐第二种更贴合C++风格的写法:

方案一:用静态成员函数做包装器(兼容C API)

我们可以先写一个静态成员函数,它符合g_timeout_add要求的回调签名,然后把类实例的this指针作为数据传递进去,在静态函数里再转成实例指针调用真正的成员函数。如果需要传递额外的processed参数,还可以把this和processed打包成结构体:

#include <gtkmm/window.h>
#include <iostream>
#include <utility>

class MainWindow : public Gtk::Window {
public:
    MainWindow(int processed) {
        // 把当前实例指针和processed打包成结构体传递
        auto* data = new std::pair<MainWindow*, int>(this, processed);
        g_timeout_add(100, &MainWindow::static_callback, data);
    }

    // 记得在析构里清理内存(避免泄漏)
    ~MainWindow() override {
        // 如果定时还在运行,建议先通过g_source_remove移除对应的源,这里简化处理
    }

private:
    // 静态成员函数,完全符合GSourceFunc的签名
    static gboolean static_callback(gpointer data) {
        // 解析传递过来的数据
        auto* pair = static_cast<std::pair<MainWindow*, int>*>(data);
        MainWindow* window = pair->first;
        int processed_val = pair->second;

        // 调用实际的成员回调函数
        bool keep_running = window->callbackFunc(processed_val);

        // 如果不需要继续定时,清理内存
        if (!keep_running) {
            delete pair;
        }

        // 转换为gboolean返回(TRUE继续,FALSE停止)
        return keep_running ? TRUE : FALSE;
    }

    // 你实际的业务回调函数
    bool callbackFunc(int processed_val) {
        // 这里写你的处理逻辑
        std::cout << "Timeout triggered, processed value: " << processed_val << std::endl;

        // 返回true继续定时,返回false停止
        return true;
    }
};

方案二:用Gtkmm的C++风格超时信号(推荐)

Gtkmm作为GLib的C++绑定,提供了更友好的Glib::signal_timeout()接口,不需要手动处理静态包装和指针转换,直接用sigc::mem_fun绑定成员函数,还能通过sigc::bind传递额外参数:

#include <gtkmm/window.h>
#include <glibmm/main.h>
#include <iostream>

class MainWindow : public Gtk::Window {
public:
    MainWindow(int processed) {
        // 绑定超时信号,100毫秒触发一次,同时传递processed参数
        Glib::signal_timeout().connect(
            sigc::bind(sigc::mem_fun(*this, &MainWindow::callbackFunc), processed),
            100
        );
    }

private:
    // 回调函数直接用bool返回(和gboolean兼容)
    bool callbackFunc(int processed_val) {
        std::cout << "Timeout triggered, processed value: " << processed_val << std::endl;

        // 返回true继续定时,false停止
        return true;
    }
};

关键说明:

  • 如果不需要传递额外参数,直接用sigc::mem_fun(*this, &MainWindow::callbackFunc)即可,不需要sigc::bind。
  • 两种方案中,回调函数返回true(或TRUE)表示继续触发定时,返回false(或FALSE)表示停止定时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:14:51