 |
GTK+ Forums Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
|
|
|
| Author |
Message |
|
|
nadavvin Familiar Face
Joined: 06 Dec 2007 Posts: 19
|
Posted: Thu Dec 04, 2008 9:55 am Post subject: How to draw Cairo from pixbuf |
|
|
Hello
I'm trying to create customize, not rectangle window:
http://www.gtkforums.com/viewtopic.php?t=2234
However, I found that I can't put widgets on over widgets (gtk.Image), therefore I want to draw the Image to cairo.
| Code: (Python) | 1 2 3 4 5 6 7 8 9 10
|
cr = widget.window.cairo_create()
img = gtk.Image()
img.set_from_file('1.svg')
img.show()
pixbuf = img.get_pixbuf()
pix, mask = pixbuf.render_pixmap_and_mask()
cr.set_source_pixbuf(pixbuf,0,0)
cr.paint()
|
Thw window isn't draw. |
|
| Back to top |
|
 |
dreblen Never Seen the Sunlight
Joined: 14 Jun 2007 Posts: 936 Location: Falun, WI USA
|
Posted: Thu Dec 04, 2008 3:31 pm Post subject: |
|
|
I don't quite understand what problem you're having, but I don't see the need for cairo.
If you wanted to do your own drawing from your program, then cairo would make sense, but if you're just loading a file, then something like this should work:
| Code: (Python) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import gtk
from gtk import gdk
win = gtk.Window()
win.connect('delete-event', gtk.main_quit)
# make sure we don't have decorations
win.set_decorated(False)
# realize the window to create its gdk.Window
win.realize()
# you can create a pixbuf directly, you don't need to do gtk.Image.get_pixbuf()
pbuf = gdk.pixbuf_new_from_file('test.png')
# get a gdk.Pixmap and a bitmap
pmap,mask = pbuf.render_pixmap_and_mask()
# shape combine the window
win.shape_combine_mask(mask, 0, 0)
win.show()
gtk.main() | |
|
| Back to top |
|
 |
nadavvin Familiar Face
Joined: 06 Dec 2007 Posts: 19
|
Posted: Thu Dec 04, 2008 3:59 pm Post subject: |
|
|
I want to draw the window from SVG image and put widgets on it.
you only mention the mask for the shape of the window, but not how should I paint it.
This is the test window:
I want to add on it buttons for example.
I can't since the whole window already contain onw widget, gtk.Image and it isn't allow to put widgets on it, therefore I want to "copy" the image to cairo and then I could add widgets.
Therefore I want to know, How should I draw cairo from pixmap |
|
| Back to top |
|
 |
dreblen Never Seen the Sunlight
Joined: 14 Jun 2007 Posts: 936 Location: Falun, WI USA
|
Posted: Thu Dec 04, 2008 4:08 pm Post subject: |
|
|
You shouldn't need to create a gtk.Image, just follow my example in the last post and create a gdk.Pixbuf directly (like this):
| Code: (Python) | 1
| pbuf = gdk.pixbuf_new_from_file('filename.svg') | |
|
| Back to top |
|
 |
nadavvin Familiar Face
Joined: 06 Dec 2007 Posts: 19
|
Posted: Thu Dec 04, 2008 4:13 pm Post subject: |
|
|
| dreblen wrote: | You shouldn't need to create a gtk.Image, just follow my example in the last post and create a gdk.Pixbuf directly (like this):
| Code: (Python) | 1
| pbuf = gdk.pixbuf_new_from_file('filename.svg') | |
thanks.
How do I draw now the pixbuf to the window? |
|
| Back to top |
|
 |
dreblen Never Seen the Sunlight
Joined: 14 Jun 2007 Posts: 936 Location: Falun, WI USA
|
Posted: Thu Dec 04, 2008 4:22 pm Post subject: |
|
|
| dreblen wrote: | | Code: (Python) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import gtk
from gtk import gdk
win = gtk.Window()
win.connect('delete-event', gtk.main_quit)
# make sure we don't have decorations
win.set_decorated(False)
# realize the window to create its gdk.Window
win.realize()
# you can create a pixbuf directly, you don't need to do gtk.Image.get_pixbuf()
pbuf = gdk.pixbuf_new_from_file('test.png')
# get a gdk.Pixmap and a bitmap
pmap,mask = pbuf.render_pixmap_and_mask()
# shape combine the window
win.shape_combine_mask(mask, 0, 0)
win.show()
gtk.main() | |
|
|
| Back to top |
|
 |
nadavvin Familiar Face
Joined: 06 Dec 2007 Posts: 19
|
Posted: Thu Dec 04, 2008 10:17 pm Post subject: |
|
|
| Code: (Python) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
import gtk
from gtk import gdk
win = gtk.Window()
win.connect('delete-event', gtk.main_quit)
# make sure we don't have decorations
win.set_decorated(False)
# realize the window to create its gdk.Window
win.realize()
# you can create a pixbuf directly, you don't need to do gtk.Image.get_pixbuf()
pbuf = gdk.pixbuf_new_from_file('1.svg')
# get a gdk.Pixmap and a bitmap
pmap,mask = pbuf.render_pixmap_and_mask()
# shape combine the window
win.shape_combine_mask(mask, 0, 0)
win.show()
|
I got transparent window that I ran it.
Also I got selection tool and after I selected part from the screen, the program failed and gave the following errors:
| Code: (Plaintext) | 1 2 3 4 5
|
from: can't read /var/mail/gtk
./my5.py: line 4: syntax error near unexpected token `('
./my5.py: line 4: `win = gtk.Window()
|
X server crash after some runnings of the program (It's happen more than once) |
|
| Back to top |
|
 |
nadavvin Familiar Face
Joined: 06 Dec 2007 Posts: 19
|
Posted: Thu Dec 04, 2008 10:32 pm Post subject: |
|
|
I don't get the error and X isn't crash when I add your changes to the orginal file:
| Code: (Python) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#!/usr/bin/env python
#PyCairoShape clock
#(c) 2007 Nicolas Trangez - ikke at nicolast dot be
#Released under GPL v2
#All imports we need
import sys
import gobject
import pango
import pygtk
pygtk.require('2.0')
import gtk
from gtk import gdk
import cairo
from datetime import datetime
import math
#Yeah, globals. Warning: this code is messy
supports_alpha = False
win = None
shift_pressed = False
img = None
def expose(widget, event):
global supports_alpha, img
pixbuf = gdk.pixbuf_new_from_file('1.svg')
pix, mask = pixbuf.render_pixmap_and_mask()
win.shape_combine_mask(mask, 0, 0)
return False
#If screen changes, it could be possible we no longer got rgba colors
def screen_changed(widget, old_screen=None):
global supports_alpha
screen = widget.get_screen()
colormap = screen.get_rgba_colormap()
supports_alpha = True
widget.set_colormap(colormap)
return True
#Queue a redraw of our window every second
def update_clock():
# global win
# win.queue_draw()
return True
#Our widget (window) is clicked
def clicked(widget, event):
global win
win.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)
#This should be obvious
def main(args):
global win
win = gtk.Window()
#win.set_property("skip-taskbar-hint", True)
win.set_title('PyCairoShape clock')
win.connect('delete-event', gtk.main_quit)
win.set_app_paintable(True)
win.connect('expose-event', expose)
win.connect('screen-changed', screen_changed)
win.set_decorated(True)
win.add_events(gdk.BUTTON_PRESS_MASK)
win.connect('button-press-event', clicked)
screen_changed(win)
gobject.timeout_add(1000, update_clock)
win.show_all()
gtk.main()
return True
if __name__ == '__main__':
sys.exit(main(sys.argv))
|
It gave transparent window and the shape_combine_mask cover all the window, any click inside move to anywhere behind the window. |
|
| Back to top |
|
 |
dreblen Never Seen the Sunlight
Joined: 14 Jun 2007 Posts: 936 Location: Falun, WI USA
|
Posted: Thu Dec 04, 2008 11:01 pm Post subject: |
|
|
So, are you still having a problem?
Regardless, here's a slightly modified version of your code with some tips (=comments marked with 'dreblen') for getting rid of global win:
| Code: (Python) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #!/usr/bin/env python
#PyCairoShape clock
#(c) 2007 Nicolas Trangez - ikke at nicolast dot be
#Released under GPL v2
#All imports we need
import sys
import gobject
import pango
import pygtk
pygtk.require('2.0')
import gtk
from gtk import gdk
import cairo
from datetime import datetime
import math
#Yeah, globals. Warning: this code is messy
supports_alpha = False
# dreblen - At this point, win doesn't need to be global
#win = None
# /dreblen
shift_pressed = False
img = None
# dreblen - You can use the widget argument (renamed to win) instead of global win
def expose(win, event): # -widget, +win
# /dreblen
global supports_alpha, img
pixbuf = gdk.pixbuf_new_from_file('1.svg')
pix, mask = pixbuf.render_pixmap_and_mask()
win.shape_combine_mask(mask, 0, 0)
return False
#If screen changes, it could be possible we no longer got rgba colors
def screen_changed(widget, old_screen=None):
global supports_alpha
screen = widget.get_screen()
colormap = screen.get_rgba_colormap()
supports_alpha = True
widget.set_colormap(colormap)
return True
#Queue a redraw of our window every second
def update_clock():
# global win
# win.queue_draw()
return True
#Our widget (window) is clicked
# dreblen - You can use the widget argument (renamed to win) instead of global win
def clicked(win, event): # -widget, +win
# No need for global
# global win
# /dreblen
win.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)
#This should be obvious
def main(args):
# dreblen - no need for global
# global win
# /dreblen
win = gtk.Window()
#win.set_property("skip-taskbar-hint", True)
win.set_title('PyCairoShape clock')
win.connect('delete-event', gtk.main_quit)
win.set_app_paintable(True)
win.connect('expose-event', expose)
win.connect('screen-changed', screen_changed)
win.set_decorated(True)
win.add_events(gdk.BUTTON_PRESS_MASK)
win.connect('button-press-event', clicked)
screen_changed(win)
gobject.timeout_add(1000, update_clock)
win.show_all()
gtk.main()
return True
if __name__ == '__main__':
sys.exit(main(sys.argv)) | |
|
| Back to top |
|
 |
nadavvin Familiar Face
Joined: 06 Dec 2007 Posts: 19
|
Posted: Thu Dec 04, 2008 11:32 pm Post subject: |
|
|
I still got transparent window.
However when I use in gtk.Image I could pass it to cairo like this:
| Code: (Python) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
def expose(widget, event):
global supports_alpha, img
#Get a cairo context
cr = widget.window.cairo_create()
#Make the window transparent
cr.set_source_rgba(1.0, 1.0, 1.0, 0.0) # HERE
cr.set_operator(cairo.OPERATOR_SOURCE)
img = gtk.Image()
img.set_from_file('1.svg')
img.show()
pixbuf = img.get_pixbuf()
pix, mask = pixbuf.render_pixmap_and_mask()
cr.set_source_pixmap(pix,0,0)
cr.paint()
#Once everything has been drawn, create our XShape mask
win.input_shape_combine_mask(mask, 0, 0)
return False
|
However the window background is black where the pix isn't cover instead of transparent.
Why doesn't pixbuf = gdk.pixbuf_new_from_file('1.svg') work as expected? |
|
| Back to top |
|
 |
dreblen Never Seen the Sunlight
Joined: 14 Jun 2007 Posts: 936 Location: Falun, WI USA
|
Posted: Fri Dec 05, 2008 4:34 pm Post subject: |
|
|
| nadavvin wrote: | | I still got transparent window. |
Isn't that what you want?
| nadavvin wrote: | However when I use in gtk.Image I could pass it to cairo like this:
| Code: (Python) | 1
| # code snipped | |
Why do you want to use cairo?
| nadavvin wrote: | | However the window background is black where the pix isn't cover instead of transparent. |
Do you mean that the shape_combine isn't working?
| nadavvin wrote: | | Why doesn't pixbuf = gdk.pixbuf_new_from_file('1.svg') work as expected? |
How do you expect it to work, and what is it doing? |
|
| Back to top |
|
 |
nadavvin Familiar Face
Joined: 06 Dec 2007 Posts: 19
|
Posted: Fri Dec 05, 2008 6:10 pm Post subject: |
|
|
| dreblen wrote: |
Isn't that what you want?
|
No, I don't want entirely transparent window, but a shaped window that part of it are transparent.
| dreblen wrote: |
Why do you want to use cairo?
|
I don't know about over way.
| dreblen wrote: |
Do you mean that the shape_combine isn't working?
nadavvin wrote:
Why doesn't pixbuf = gdk.pixbuf_new_from_file('1.svg') work as expected?
How do you expect it to work, and what is it doing?
|
shape_combine work but pixbuf_new_from_file isn't load the image (It isn't give error, but the mask empty)
I can click anywhere on the window and the input move to anywhere behind the window.
I remind what I want to do:
shaped window with background image and widgets on it. |
|
| Back to top |
|
 |
dreblen Never Seen the Sunlight
Joined: 14 Jun 2007 Posts: 936 Location: Falun, WI USA
|
Posted: Fri Dec 05, 2008 7:04 pm Post subject: |
|
|
| nadavvin wrote: | | No, I don't want entirely transparent window, but a shaped window that part of it are transparent. |
Sorry, that's what I meant...
| nadavvin wrote: | | I don't know about over way. |
I guess I should have asked a different question: What are you using cairo for?
| nadavvin wrote: | | shape_combine work but pixbuf_new_from_file isn't load the image (It isn't give error, but the mask empty) |
I don't have this problem. Can you upload your svg somewhere to see if that's the problem?
| nadavvin wrote: | | I can click anywhere on the window and the input move to anywhere behind the window. |
You're saying that the window isn't getting focus? What version of GTK+ do you use? |
|
| Back to top |
|
 |
nadavvin Familiar Face
Joined: 06 Dec 2007 Posts: 19
|
Posted: Sat Dec 06, 2008 4:15 am Post subject: |
|
|
| Quote: | | I guess I should have asked a different question: What are you using cairo for? |
To paint the window.
| Quote: | | I don't have this problem. Can you upload your svg somewhere to see if that's the problem? |
http://nadavvin.com/1.svg
| Quote: |
You're saying that the window isn't getting focus? What version of GTK+ do you use?
|
| Code: (Plaintext) | 1 2 3
|
ii libgtk2.0-0 2.14.4-0ubuntu1 The GTK+ graphical user interface library
| |
|
| Back to top |
|
 |
dreblen Never Seen the Sunlight
Joined: 14 Jun 2007 Posts: 936 Location: Falun, WI USA
|
Posted: Sat Dec 06, 2008 4:48 am Post subject: |
|
|
Okay, I still don't understand why you need to use cairo if you're loading an svg, but I know why it appears that your window is transparent.
It's because your svg is larger than the default window size.
If you resize the window, you'll see that the rest of shape is there too, it's just outside of the window. |
|
| Back to top |
|
 |
|
Powered by phpBB © 2001, 2005 phpBB Group CodeBB 1.0 Beta 2
|