Dear all,
I have been trying to use get_snapshot to create a raster image of a
widget. This widget is in a gtk.TextView, so it may or may not be
visible, depending on the scrolling position. What I've found is that
everything works when the widget is fully visible. If the widget is
completely obscured, I get junk, and if it is partially obscured, only
the visible part of the widget shows up okay in the image.
Attached is a sample application which demonstrates the problem. When
the "Take Snapshot" button is pressed, get_snapshot() is called on a
gtk.Label at the top of the TextView, and the resultant image is saved
to snapshot.png. For me at least, this works when the Label is visible
in the TextView, but produces a junk image when the TextView has been
scrolled downwards.
Previously, I had been using GTK 2.16.1. With that version, I found
that I could get things to work if I wrapped the Label in a
gtk.EventBox. I theorized that the X-window associated with the
EventBox gave the widget something to draw onto even when I was not
visible. Upon upgrading to 2.18, however, I've found that this hack no
longer works.
I'm very much new to GTK programming, so I apologize if this is an
obvious issue to everyone else. My questions are:
- Am I using get_snapshot() correctly?
- Is get_snapshot supposed to work with non-visible widgets?
- If so, should I submit this as a bug?
- If not, is there another way to render existing widgets to raster images?
Thank you,
Robert
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk
class App:
def delete_event(self, widget, event, data=None):
return False
def destroy(self, widget, data=None):
gtk.main_quit()
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("delete_event", self.delete_event)
self.window.connect("destroy", self.destroy)
self.button = gtk.Button("Take snapshot")
self.button.connect("pressed", self.snapshot, None)
self.target = gtk.Label("Target")
tv = gtk.TextView()
tb = tv.get_buffer()
tb.set_text("\nScroll down until the label above label is offscreen. Then take snapshot.")
anchor = tb.create_child_anchor(tb.get_start_iter())
tv.add_child_at_anchor(self.target, anchor)
tv.set_wrap_mode(gtk.WRAP_WORD)
tv.set_size_request(150,50)
box = gtk.VBox()
box.pack_start(tv, False)
box.pack_start(self.button, False)
self.window.add(box)
self.window.show_all()
def main(self):
gtk.main()
def snapshot(self, widget, data=None):
x,y,w,h = self.target.allocation
pm = self.target.get_snapshot()
pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, w, h)
pb.get_from_drawable(pm, pm.get_colormap(), 0, 0, 0, 0, -1, -1)
pb.save("snapshot.png", "png")
if __name__ == "__main__":
app = App()
app.main()
_______________________________________________
pygtk mailing list pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/