GTK+ Forums Forum Index GTK+ Forums
Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to draw Cairo from pixbuf
Goto page 1, 2  Next
 
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming
Author Message
nadavvin
Familiar Face


Joined: 06 Dec 2007
Posts: 19

PostPosted: Thu Dec 04, 2008 9:55 am    Post subject: How to draw Cairo from pixbuf Reply with quote

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

PostPosted: Thu Dec 04, 2008 3:31 pm    Post subject: Reply with quote

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

PostPosted: Thu Dec 04, 2008 3:59 pm    Post subject: Reply with quote

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

PostPosted: Thu Dec 04, 2008 4:08 pm    Post subject: Reply with quote

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

PostPosted: Thu Dec 04, 2008 4:13 pm    Post subject: Reply with quote

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

PostPosted: Thu Dec 04, 2008 4:22 pm    Post subject: Reply with quote

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

PostPosted: Thu Dec 04, 2008 10:17 pm    Post subject: Reply with quote

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

PostPosted: Thu Dec 04, 2008 10:32 pm    Post subject: Reply with quote

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

PostPosted: Thu Dec 04, 2008 11:01 pm    Post subject: Reply with quote

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

PostPosted: Thu Dec 04, 2008 11:32 pm    Post subject: Reply with quote

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

PostPosted: Fri Dec 05, 2008 4:34 pm    Post subject: Reply with quote

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

PostPosted: Fri Dec 05, 2008 6:10 pm    Post subject: Reply with quote

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

PostPosted: Fri Dec 05, 2008 7:04 pm    Post subject: Reply with quote

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

PostPosted: Sat Dec 06, 2008 4:15 am    Post subject: Reply with quote

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

PostPosted: Sat Dec 06, 2008 4:48 am    Post subject: Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 


Powered by phpBB © 2001, 2005 phpBB Group
CodeBB 1.0 Beta 2
Protected by Anti-Spam ACP