0

I want to build a table in a window; then in every cell i want to put a Gtk.DrawingArea and then drawing a rectangle for everyone.

But I can't understand how to create the cairo context, because i get this error:

AttributeError: 'NoneType' object has no attribute 'cairo_create'

Here below i show you my code (it is still a prototype, but i want to learn how to bind a cairo context to the right object):

#!/usr/bin/python3  
import pygtk
pygtk.require('2.0')
import gtk

class collega_GUI:  
    def __init__(self):
            self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
            self.window.set_title("Drawing Area Example")
            self.window.connect("destroy", lambda w: gtk.main_quit())

            self.rows=3
            self.columns=3
            self.table = gtk.Table(self.rows,self.columns,True)
            self.window.add(self.table)

            self.DrawingArea_list = list()
            for i in range(self.rows*self.columns):
                self.DrawingArea_list.append(gtk.DrawingArea())

            for row in range(0,self.rows):
                for column in range(0,self.columns):
                    cr = self.DrawingArea_list[row*2+column].window.cairo_create()
                cr.set_line_width(9)
                cr.set_source_rgb(0.7, 0.2, 0.0)
                cr.rectangle(0.25, 0.25, 0.5, 0.5)
                cr.stroke()
                cr.set_source_rgb(0.5, 0.2, 0.3)
                cr.fill()
                self.table.attach(self.DrawingArea_list[row*2+column], row, row+1, column, column+1)

                self.window.show()

if __name__ == '__main__':
    prova = collega_GUI()
    gtk.main()
pevik
  • 4,523
  • 3
  • 33
  • 44
FrancescoN
  • 2,146
  • 12
  • 34
  • 45

1 Answers1

1

As the error message says the GdkWindow does not exist at that point, so you can't draw yet.

All the drawing should happen in the appropriate signal handler of the DrawingAreas: In GTK 2 the signal is "expose-event" and in the signal handler you should create the Cairo context and draw every time the handler is called. This answer has an example using a DrawingArea subclass (which is a sensible idea)

Just a warning, in GTK3 this part is a bit different.

pevik
  • 4,523
  • 3
  • 33
  • 44
Jussi Kukkonen
  • 13,857
  • 1
  • 37
  • 54
  • excuse me, but the DrawingArea already exists.. i've created it before. In **self.DrawingArea_list** there are 9 DrawingArea. So maybe is beacause i have to draw inside a signal handler for an expose-event – FrancescoN Jan 18 '14 at 18:37
  • drawingareas exist but the GdkWindows of those drawingareas do not. Not before the drawingareas are realized (see "realize" signal if you need to know when this happens). Anyway, you are correct that the only correct place to do drawing in a GtkWidget is in "expose-event" handler. – Jussi Kukkonen Jan 18 '14 at 19:21
  • Ok but.. i can't have a window for every DrawingArea.. how can i do it? – FrancescoN Jan 18 '14 at 23:32
  • That doesn't make sense... _Why_ can't your DrawingAreas have GdkWindows? Are you confusing GdkWindow with a GtkWindow -- the former is just a region of screen and many widgets have one. – Jussi Kukkonen Jan 19 '14 at 10:35
  • I actually want to say that i don't want to make a window for every DrawingArea, because i need to have 9-20-50 DrawingArea in a single window; everyone DrawingArea inside a Gtk.Table cell – FrancescoN Jan 19 '14 at 16:10