gtkdrawpygobjectdrawingarea

Drawing in a Gtk.DrawingArea


I'd like to draw inside my Gtk.DrawingArea objects. I have to connect the drawing function to the "draw" event, not to the "expose-event", because i'm working with gtk3.

But this doesn't work.

Here is my code:

def draw(widget, context, args=()):

    context.set_source_rgb(0.9, 0, 0.1) #rosso
    context.rectangle(0, 0, widget.get_allocated_width(), widget.get_allocated_height())
    context.fill()


builder = Gtk.Builder()
builder.add_from_file('menuitem.glade')

builder.get_object('drawingarea1').connect("draw", draw)
builder.get_object('drawingarea1').show()

builder.get_object('window1').show() #there are many drawing areas inside a window (they are inside a grid)

Gtk.main()

Solution

  • Adding DrawingAreas to a Grid is a bit problematic if hexpand and vexpand are not set. Additionally adding width_request and height_request is needed (or some other layout organization which forces the DrawingArea to have a size), otherwise the initial window size will be tiny or not visible. The following shows your code working with a Grid and two DrawingAreas:

    from gi.repository import Gtk
    
    ui = """
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Generated with glade 3.16.1 -->
    <interface>
      <requires lib="gtk+" version="3.10"/>
      <object class="GtkWindow" id="window1">
        <property name="can_focus">False</property>
        <child>
          <object class="GtkGrid" id="grid1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="column_spacing">4</property>
            <child>
              <object class="GtkDrawingArea" id="drawingarea1">
                <property name="width_request">100</property>
                <property name="height_request">100</property>
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
              </object>
              <packing>
                <property name="left_attach">0</property>
                <property name="top_attach">0</property>
                <property name="width">1</property>
                <property name="height">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkDrawingArea" id="drawingarea2">
                <property name="width_request">100</property>
                <property name="height_request">100</property>
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
              </object>
              <packing>
                <property name="left_attach">1</property>
                <property name="top_attach">0</property>
                <property name="width">1</property>
                <property name="height">1</property>
              </packing>
            </child>
          </object>
        </child>
      </object>
    </interface>
    """
    
    def draw(widget, context, color=(0, 0, 0)):
        context.set_source_rgb(*color)
        context.rectangle(0, 0, widget.get_allocated_width(), widget.get_allocated_height())
        context.fill()
    
    builder = Gtk.Builder.new_from_string(ui, -1)
    builder.get_object('drawingarea1').connect("draw", draw, (0.9, 0, 0.1))
    builder.get_object('drawingarea2').connect("draw", draw, (0.1, 0, 0.9))
    
    window = builder.get_object('window1')
    window.connect('destroy', Gtk.main_quit)
    window.show_all()
    
    Gtk.main()