当派生 class 不调用超级 class 的构造函数时,绘制信号不会在 GTKMM 中触发

Draw signal doesn't get fired in GTKMM, when derived class doesn't call a superclass's constructor

DrawingArea.hpp

#ifndef __DRAWINGAREA
#define __DRAWINGAREA

#include <gtkmm.h>

class DrawingArea : public Gtk::DrawingArea
{
public:
    bool on_my_draw(const Cairo::RefPtr<Cairo::Context>& cr);

    DrawingArea(GtkDrawingArea* &cobject, const Glib::RefPtr<Gtk::Builder>& builder);
};
#endif // __DRAWINGAREA

DrawingArea.cpp

#include "DrawingArea.hpp"

#include <iostream>

DrawingArea::DrawingArea(GtkDrawingArea* &cobject, const Glib::RefPtr<Gtk::Builder>& builder)
{
    this->signal_draw().connect(sigc::mem_fun(this, &DrawingArea::on_my_draw));
}

bool DrawingArea::on_my_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
    std::cout << "i am here" << std::endl;
}

将其编译到应用程序中后,我测试了 DrawingArea 构造函数确实被触发(我使用 get_widget_derived 将其连接到 Glade,但这在这里不重要) .

我希望在启动应用程序时看到 "I am here",或者当它需要重绘 DrawingArea 时看到 "I am here",但由于某种原因没有发生。

尽管该区域已经显示,但我尝试在它所属的 window 上启动 show_all_children,但这没有帮助。


现在尝试添加

到 .hpp:

bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr) override;

然后到 .cpp:

bool DrawingArea::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
    std::cout << "i am here!!!" << std::endl;
}

这没有帮助。

也曾尝试将 false 作为第二个参数传递给 connect(),但这没有帮助。

覆盖默认处理程序更简单 - on_draw(),如这个简单示例所示: https://developer.gnome.org/gtkmm-tutorial/stable/sec-cairo-drawing-lines.html.en#cairo-example-lines

这些信号 return bool 通常必须连接 "before" 才能调用额外的信号处理程序: https://developer.gnome.org/gtkmm-tutorial/stable/sec-xeventsignals.html.en#signal-handler-sequence

这个问题很有趣,与人们预期的完全不同,所以我会 post 我得到的答案。

问题是我需要正确初始化对象。具体来说,我没有调用超类的构造函数。我需要做的:

DrawingArea::DrawingArea(GtkDrawingArea* cobject, const Glib::RefPtr<Gtk::Builder>& builder)
    : Gtk::DrawingArea(cobject) // <--- this is a very important bit
{
   //...
}

否则不仅信号连接丢失(这是可以理解的,因为处理所需函数调用的整个对象部分都消失了),甚至被覆盖的 on_draw 也停止工作(这是我仍然不明白的地方)。