Search code examples
c++qtgtkglibgobject

How to use GTK signals?


I am new to GTK and I'm coming from a Qt background. I'm trying to figure out how signals work in GTK and I'm trying to emit one but it doesn't work. I found it surprising that I couldn't find a decent code example which emits a GTK signal that works. This is my code so far(I'm using Qt Creator):

Test_Gtk.pro:

#-------------------------------------------------
#
# Project created by QtCreator 2015-04-26T12:42:38
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Test_Gtk
TEMPLATE = app

SOURCES += main.cpp \
    myfirstobject.cpp \
    mysecondobject.cpp


HEADERS += \
    myfirstobject.h \
    mysecondobject.h

unix:!macx{
    # Make sure you install libappindicator-dev
    INCLUDEPATH += /usr/include/glib-2.0
    INCLUDEPATH += /usr/include/gtk-2.0
    INCLUDEPATH += /usr/lib/x86_64-linux-gnu/glib-2.0/include
    INCLUDEPATH += /usr/lib/x86_64-linux-gnu/gtk-2.0/include
    INCLUDEPATH += /usr/include/cairo
    INCLUDEPATH += /usr/include/pango-1.0
    INCLUDEPATH += /usr/include/gdk-pixbuf-2.0
    INCLUDEPATH += /usr/include/atk-1.0

    LIBS += -L/usr/lib/x86_64-linux-gnu -lgobject-2.0
    LIBS += -L/usr/lib/x86_64-linux-gnu -lgtk-x11-2.0
}

myfirstobject.h:

#ifndef MYFIRSTOBJECT_H
#define MYFIRSTOBJECT_H

#include <QObject>

#ifdef Q_OS_LINUX
#undef signals
extern "C" {
    #include <gtk/gtk.h>
}
#define signals public
#endif

class MyFirstObject : public GObject
{
public:
    MyFirstObject();
    ~MyFirstObject();

    void emitMySignal();
};

#endif // MYFIRSTOBJECT_H

myfirstobject.cpp:

#include "myfirstobject.h"

MyFirstObject::MyFirstObject()
{
    g_signal_new("my-signal",
                 G_TYPE_OBJECT, G_SIGNAL_RUN_FIRST,
                 0, NULL, NULL,
                 g_cclosure_marshal_VOID__POINTER,
                 G_TYPE_NONE, 1, G_TYPE_POINTER);
}

MyFirstObject::~MyFirstObject()
{

}

void MyFirstObject::emitMySignal()
{
    g_signal_emit_by_name (this, "my-signal");
}

mysecondobject.h:

#ifndef MYSECONDOBJECT_H
#define MYSECONDOBJECT_H

#include <QObject>

#ifdef Q_OS_LINUX
#undef signals
extern "C" {
    #include <gtk/gtk.h>
}
#define signals public
#endif

class MyFirstObject;

class MySecondObject : public GObject
{
public:
    MySecondObject(MyFirstObject *obj);
    ~MySecondObject();

    void mySlot();

private:
    MyFirstObject *m_obj;
};

#endif // MYSECONDOBJECT_H

mysecondobject.cpp:

#include "mysecondobject.h"
#include "myfirstobject.h"

#include <QDebug>

MySecondObject::MySecondObject(MyFirstObject *obj) : m_obj(obj)
{
    g_signal_connect(m_obj, "my-signal", G_CALLBACK(&MySecondObject::mySlot), 0);
}

MySecondObject::~MySecondObject()
{

}

void MySecondObject::mySlot()
{
    qDebug() << "mySlot was called";
}

main.cpp:

#include <QCoreApplication>

#include "myfirstobject.h"
#include "mysecondobject.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyFirstObject *o1 = new MyFirstObject;
    MySecondObject *o2 = new MySecondObject(o1);
    o1->emitMySignal();

    return a.exec();
}

The code is simple. I emit a signal from MyFirstObject and I expect a callback to be called in MySecondObject. The problem is that the callback is never called. Can you please tell me what am I doing wrong? Is there a place where GTK signals are well explained or some code examples?

As far as I learned so far GObject in GTK is like QObject in Qt and GtkObject in GTK is like QWidget in Qt. Is this true?


Solution

  • The gtkmm tutorial recommends using libsigc++ to create signals from C++ code; gtkmm uses libsigc++ internally to wrap the signals which are defined in C in GTK+ itself.

    https://developer.gnome.org/gtkmm-tutorial/stable/chapter-custom-signals.html.en

    A (too verbose to copy here) example is provided too: https://developer.gnome.org/gtkmm-tutorial/stable/chapter-custom-signals-example.html.en