You can actually do this using a TextView widget. First you should set editable to true:
You will need to get its textbuffer which is the textviews data:
buffer = textview.get_buffer()
Then using that buffer you can get and set the data in it. to get the text currently in the buffer use:
buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), false)
The first and second arguments are the range to get the text, in this case all off it. The last argument specifies whether you would like to get hidden characters, in this case false. To insert text you can use the following:
buffer.insert(buffer.get_end_iter(), "Sample text")
The first argument specifies where to insert the text, in this case at the end. the second argument is the text to insert. To replace all the data in the buffer you can use:
This will replace everything in the buffer with "Sample text". To insert an image you need to create a pixbuf to do this use the following:
pixbuf = gtk.gdk.pixbuf_new_from_file(filename)
To resize the pixbuf use:
pixbuf.scale_simple(dest_width, dest_height, gtk.gdk.INTERP_BILINEAR)
The first two arguments are the new width and height, the third argument is the interpolation type which controls how it scales (there are four types which can be found here). You can then add this pixbuf to the buffer using:
This will insert an image at the end of the buffer.
You can also do things like add widgets, set margins, copy and paste from clipboard, insert at the cursor, etc. but you can look at the links below for that.
Edit: For a formatted save/load you can use the textbuffers serialization method. First you should use its register_serialize_tagset() method:
format = buffer.register_serialize_tagset()
Next you can use its serialize method to get the serialized data:
data buffer.serialize(buffer, format, buffer.get_start_iter(), buffer.get_end_iter())
This will return the data in textbuffer's internal format, which you can save to a file. To load this data first call textbuffer's register_deserialize_tagset() method:
format = emptyBuffer.register_deserialize_tagset()
Then you can load the data using its deserialize() method:
emptyBuffer.deserialize(emptyBuffer, format, emptyBuffer.get_end_iter(), data)
This will load the data into the textbuffer.
Edit2: if you want the user to be able to drag to move and resize you will have to instead load the pixbuf into an image widget, the image widget into a event box, the event box into a child anchor to put into the the textview you can handle x events for that widget and write code in the handlers to that will move or resize the image.