[pygtk] some more problems in moving a widget
Vihan Pandey
vihanpandey at gmail.com
Thu Feb 16 19:11:17 WST 2006
Hello all,
i'm still facing some problems in making a widget move.
For Johan :
i checked out :
http://cvs.gnome.org/viewcvs/gnome-python/pygtk/examples/gtk/widget.py?view=markup
and integrated the two programs (mine and the one above).
The resultant code :
import sys
import gobject
import pango
import gtk
from gtk import gdk
if gtk.pygtk_version < (2, 8):
print "PyGtk 2.8 or later required for this example"
raise SystemExit
try:
import cairo
except ImportError:
raise SystemExit("cairo required for this example")
class PyGtkWidget(gtk.Widget):
def __init__(self):
gtk.Widget.__init__(self)
#self._layout = self.create_pango_layout(text)
#self._layout.set_font_description(pango.FontDescription("Sans Serif
16"))
# GtkWidget
def do_realize(self):
# The do_realize method is responsible for creating GDK (windowing
system)
# resources. In this example we will create a new gdk.Window which
we
# then draw on
# First set an internal flag telling that we're realized
self.set_flags(self.flags() | gtk.REALIZED)
# Create a new gdk.Window which we can draw on.
# Also say that we want to receive exposure events by setting
# the event_mask
self.window = gdk.Window(
self.get_parent_window(),
width=self.allocation.width,
height=self.allocation.height,
window_type=gdk.WINDOW_CHILD,
wclass=gdk.INPUT_OUTPUT,
event_mask=self.get_events() | gdk.EXPOSURE_MASK)
# Associate the gdk.Window with ourselves, Gtk+ needs a reference
# between the widget and the gdk window
self.window.set_user_data(self)
# Attach the style to the gdk.Window, a style contains colors and
# GC contextes used for drawing
self.style.attach(self.window)
# The default color of the background should be what
# the style (theme engine) tells us.
self.style.set_background(self.window, gtk.STATE_NORMAL)
self.window.move_resize(*self.allocation)
def do_unrealize(self):
# The do_unrealized method is responsible for freeing the GDK
resources
# De-associate the window we created in do_realize with ourselves
self.window.set_user_data(None)
def do_size_request(self, requisition):
# The do_size_request method Gtk+ is calling on a widget to ask
# it the widget how large it wishes to be. It's not guaranteed
# that gtk+ will actually give this size to the widget
# In this case, we say that we want to be as big as the
# text is, plus a little border around it.
width, height = self._layout.get_size()
requisition.width = width // pango.SCALE + BORDER_WIDTH*4
requisition.height = height // pango.SCALE + BORDER_WIDTH*4
def do_size_allocate(self, allocation):
# The do_size_allocate is called by when the actual size is known
# and the widget is told how much space could actually be allocated
# Save the allocated space
self.allocation = allocation
# If we're realized, move and resize the window to the
# requested coordinates/positions
if self.flags() & gtk.REALIZED:
self.window.move_resize(*allocation)
def do_expose_event(self, widget, event):
# The do_expose_event is called when the widget is asked to draw
itself
# Remember that this will be called a lot of times, so it's usually
# a good idea to write this code as optimized as it can be, don't
# Create any resources in here.
# In this example, draw a rectangle in the foreground color
self.context = widget.window.cairo_create()
# set a clip region for the expose event
self.context.rectangle(event.area.x,
event.area.y,
event.area.width,
event.area.height)
self.context.clip()
#self.draw(self.context)
return False
#def draw(self, context):
rect = self.get_allocation()
x = rect.width / 2
print 'X cordinate is : '
print x
y = rect.height / 2
print 'Y cordinate is : '
print y
# Ellipse co-ordinates, default : centroid of Rectangle
ex = x
ey = y
ew = rect.width / 4.0
eh = rect.height / 12.0
context.save()
context.translate (ex, ey)
# edited by vihan
context.scale (ew / 2.0 , eh / 2.0)
#context.arc (0, 0, 1., 0., 2 * math.pi)
# edited by vihan
#
# context.arc(x displacement, y displacement, 'another ellipse',
# 'slice ellipse', start point, end point
#
context.arc (0, 0, 1., 0, 2 * math.pi)
context.fill_preserve()
# This sets the colour of the Ellipse via R, G, B levels 0.0 - 1.0
context.set_source_rgb(0, 0, 1)
context.stroke()
context.restore ()
gobject.type_register(PyGtkWidget)
def main(args):
win = gtk.Window()
win.set_border_width(5)
win.set_title('Widget test')
win.connect('delete-event', gtk.main_quit)
frame = gtk.Frame("Example frame")
win.add(frame)
w = PyGtkWidget(TEXT)
frame.add(w)
win.show_all()
gtk.main()
def main(args):
win = gtk.Window()
win.set_border_width(5)
win.set_title('Widget test')
win.connect('delete-event', gtk.main_quit)
frame = gtk.Frame("Example frame")
win.add(frame)
w = PyGtkWidget()
frame.add(w)
win.show_all()
gtk.main()
if __name__ == '__main__':
sys.exit(main(sys.argv))
But i get the follwing error :
Traceback (most recent call last):
File "ellipse-move.py", line 73, in do_size_request
width, height = self._layout.get_size()
AttributeError: 'PyGtkWidget' object has no attribute '_layout'
TypeError: do_expose_event() takes exactly 3 arguments (2 given)
i never faced this in the ellipse prototypes. There's another question
around the same, why is it that one can only add one widget object onto a
gtk drawing area ? i tried the following :
import gtk
import math
class Ellipse(gtk.DrawingArea):
def __init__(self):
gtk.DrawingArea.__init__(self)
self.connect("expose_event", self.expose)
def expose(self, widget, event):
self.context = widget.window.cairo_create()
# set a clip region for the expose event
self.context.rectangle(event.area.x, event.area.y,
event.area.width, event.area.height)
self.context.clip()
self.draw(self.context)
return False
def draw(self, context):
rect = self.get_allocation()
x = rect.width / 2
print 'X cordinate is : '
print x
y = rect.height / 2
print 'Y cordinate is : '
print y
# Ellipse co-ordinates, default : centroid of Rectangle
ex = x
ey = y
ew = rect.width / 4.0
eh = rect.height / 12.0
context.save()
context.translate (ex, ey)
# edited by vihan
context.scale (ew / 2.0 , eh / 2.0)
#context.arc (0, 0, 1., 0., 2 * math.pi)
# edited by vihan
#
# context.arc(x displacement, y displacement, 'another ellipse',
# 'slice ellipse', start point, end point
#
context.arc (0, 0, 1., 0, 2 * math.pi)
context.fill_preserve()
# This sets the colour of the Ellipse via R, G, B levels 0.0 - 1.0
context.set_source_rgb(0, 0, 1)
context.stroke()
context.restore ()
#### End of class Ellipse ####
class myclass(gtk.DrawingArea):
#def __init__(self):
# gtk.DrawingArea.__init__(self)
# self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
# gtk.gdk.BUTTON1_MOTION_MASK)
# self.connect("expose_event", self.expose)
# self.connect("button_press_event", self.pressing)
# self.connect("motion_notify_event", self.moving)
# self.desp = 0
def pressing(self, widget, event):
self.pressing_x = event.x
def moving(self, widget, event):
if (self.pressing_x - event.x) > 1:
self.desp = self.desp + 0.1
else:
self.desp = self.desp - 0.1
self.pressing_x = event.x
self.draw(self.context)
self.queue_draw()
def expose(self, widget, event):
self.context = widget.window.cairo_create()
self.context.rectangle(event.area.x, event.area.y,
event.area.width, event.area.height)
self.context.clip()
self.draw(self.context)
return False
def draw(self, context):
x = 100 / 2
y = 50 / 2
context.rectangle (x + self.desp, y + self.desp, 100, 50)
context.set_source_rgb(1, 1, 1)
context.fill_preserve()
context.set_source_rgb(0, 0, 0)
context.stroke()
def main():
window = gtk.Window()
eobj = Ellipse()
eobj2 = Ellipse
robj = myclass()
window.add(eobj)
window.add(robj)
#window.add(eobj2)
window.connect("destroy", gtk.main_quit)
window.show_all()
gtk.main()
if __name__ == "__main__":
main()
This creates a 2 ellipse objects and adds them to the window. However you
can only display one at a time.
On uncommenting the window.add(eobj2) line you get the error ;
multiwidget.py:133: GtkWarning: Attempting to add a widget with type
GtkDrawingArea to a GtkWindow, but as a GtkBin subclass a GtkWindow can only
contain one widget at a time; it already contains a widget of type
GtkDrawingArea
window.add(robj)
Traceback (most recent call last):
File "multiwidget.py", line 141, in ?
main()
File "multiwidget.py", line 134, in main
window.add(eobj2)
TypeError: GtkContainer.add() argument 1 must be gtk.Widget, not
gobject.GObjectMeta
Does anyone why is this so. Moreover how do i add more than one widget onto
the window.
Sorry for me repeatedly bothering every one with my "Ellipse obsession" but
i just can't seem to get it right.
Thanks,
- vihan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.daa.com.au/pipermail/pygtk/attachments/20060216/bc333ef6/attachment-0001.htm
More information about the pygtk
mailing list