如何使用 GTK 信号

How to use GTK signals?

本文关键字:信号 GTK 何使用      更新时间:2023-10-16

我是GTK新手,我来自Qt背景。我试图弄清楚信号在GTK中是如何工作的,我试图发出一个,但它不起作用。我发现令人惊讶的是,我找不到一个像样的代码示例来发出有效的GTK信号。这是我到目前为止的代码(我正在使用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";
}

主.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();
}

代码很简单。我发出来自MyFirstObject的信号,我希望在MySecondObject中调用回调。问题是永远不会调用回调。你能告诉我我做错了什么吗?有没有一个地方可以很好地解释GTK信号或一些代码示例?

据我所知,GObject GTK就像Qt中的QObjectGTK GtkObject就像Qt中的QWidget。这是真的吗?

gtkmm 教程建议使用 libsigc++

从C++代码创建信号;gtkmm 在内部使用 libsigc++ 将 C 中定义的信号包装在 GTK+ 本身中。

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

还提供了一个(太详细而无法在此处复制)示例:https://developer.gnome.org/gtkmm-tutorial/stable/chapter-custom-signals-example.html.en