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

时间:2016-04-11 16:24:22

标签: gtkmm

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,但这在这里不重要)。< / p>

我希望在启动应用程序时看到"I am here",或者当它需要重绘DrawingArea时,但是它不会因为某种原因而发生。

尽管该区域已经显示,但我试图在它所属的窗口上启动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(),但这并没有帮助。

2 个答案:

答案 0 :(得分:1)

简单地覆盖默认处理程序 - on_draw(),就像在这个简单的例子中一样: https://developer.gnome.org/gtkmm-tutorial/stable/sec-cairo-drawing-lines.html.en#cairo-example-lines

返回bool的这些信号通常必须在“之前”连接,以便调用额外的信号处理程序: https://developer.gnome.org/gtkmm-tutorial/stable/sec-xeventsignals.html.en#signal-handler-sequence

答案 1 :(得分:1)

这个问题非常有趣,而且与人们的期望完全不同,所以我会发布我得到的答案。

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

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

如果不是这样,不仅信号连接丢失了(这是可以理解的,因为处理调用所需函数的整个对象部分已经消失),但即使被覆盖的on_draw也停止工作(和这是我仍然不理解的事情。)