Gtk3: How to use a Gtk::DrawingArea from a Custom Gtk::Window object

Hello, I’m trying to create a simple application using Gtk but I’m stump on the following issue. I’m trying to use a Gtk::DrawingArea from a custom Gtk::Window. When I add my drawing area to my window object from let’s say the main function it works fine. But when I try to add my drawing area from the constructor of my custom window class it doesn’t work. My drawing area on_draw function never get’s called :frowning:
I’m suspecting it has to do with the order in which a widget gets eventually mapped but cannot figure it out :frowning:

I’ve attached a sample of the source code of what I’m trying to achieve. I’m using gtkmm-3.0.

To build and execute my simple program run

g++ example.cpp -o example $(pkg-config --cflags --libs gtkmm-3.0) && ./example

#include <gtkmm/drawingarea.h>
#include <gtkmm/application.h>
#include <gtkmm/window.h>

class StraightLine : public Gtk::DrawingArea {
 protected:
  bool on_draw(const Cairo::RefPtr<Cairo::Context> &cr) {
    Gtk::Allocation allocation = get_allocation();
    const int width = allocation.get_width();
    const int height = allocation.get_height();
    std::printf("StraightLine::on_draw, width: %d, height: %d\n", width, height);

    int xc, yc;
    xc = width / 2;
    yc = height / 2;

    cr->set_line_width(10.0);

    // draw red lines out from the center of the window
    cr->set_source_rgb(0.8, 0.0, 0.0);
    cr->move_to(0, 0);
    cr->line_to(xc, yc);
    cr->line_to(0, height);
    cr->move_to(xc, yc);
    cr->line_to(width, yc);
    cr->stroke();

    return true;
  }

  void on_show() {
    Gtk::Widget::on_show();
    std::puts("StraightLine::on_show");
  }
  void on_realize() {
    Gtk::Widget::on_realize();
    std::puts("StraightLine::on_realize");
  }
  void on_map() {
    Gtk::Widget::on_map();
    std::puts("StraightLine::on_map");
  }
};

class ExampleWindow : public Gtk::Window
{
 public:
  ExampleWindow() {
    set_title("My Window");
    set_default_size(300, 300);

//    adding my DrawingArea from the constructor doesn't work
    StraightLine drawingArea;
    add(drawingArea);
  }
};

int main(int argc, char **argv) {
  auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

  ExampleWindow window;

//  but adding my DrawingArea here does work
//  StraightLine drawingArea;
//  window.add(drawingArea);
  window.show_all_children();

  return app->run(window);
}

That’s because you declare drawingArea inside ExampleWindow’s constructor. drawingArea gets destroyed when the constructor terminates.

Declare it as a class field, instead.

Argh… c++ rookie mistake…

Thank you very much :slight_smile:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.