Skip to content

Instantly share code, notes, and snippets.

@lubosz
Created December 2, 2015 16:50
Show Gist options
  • Save lubosz/17e093ac9b21e02e0458 to your computer and use it in GitHub Desktop.
Save lubosz/17e093ac9b21e02e0458 to your computer and use it in GitHub Desktop.
Python Interactive Cairo in GtkGLSink.
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gst', '1.0')
import math
import cairo
from gi.repository import Gtk, Gst, Gdk
from IPython import embed
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
class GtkSinkCairoApp:
w = 1280
h = 720
draw_clicked = False
draw_hovered = False
x, y, radius = w/4, h/4, 50
glow = 0.9
def press(self, widget, event):
if event.get_event_type() == Gdk.EventType.BUTTON_PRESS:
self.draw_clicked = True
elif event.get_event_type() == Gdk.EventType.BUTTON_RELEASE:
self.draw_clicked = False
@staticmethod
def quit_app(widget):
widget.hide()
Gtk.main_quit()
def window_closed(self, widget, event):
self.quit_app(widget)
def key_pressed(self, widget, key):
if key.keyval == Gdk.KEY_Escape:
self.quit_app(widget)
def on_motion(self, widget, event):
self.x = event.x
self.y = event.y
def on_draw(self, widget, cr):
if self.draw_clicked:
outer_color = .2
glow_radius = 1.08
elif self.draw_hovered:
outer_color = .8
glow_radius = 1.08
else:
outer_color = .5
glow_radius = 1.01
# clear background
cr.set_operator(cairo.OPERATOR_OVER)
cr.set_source_rgba(0.0, 0.0, 0.0, 0.0)
cr.paint()
x, y = self.x, self.y
cr.set_source_rgba(self.glow, self.glow, self.glow, 0.9)
cr.arc(x, y, self.radius * glow_radius, 0, 2 * math.pi)
cr.fill()
from_point = (x, y - self.radius)
to_point = (x, y + self.radius)
linear = cairo.LinearGradient(*(from_point + to_point))
linear.add_color_stop_rgba(0.00, outer_color, outer_color, outer_color, 1)
linear.add_color_stop_rgba(0.55, .1, .1, .1, 1)
linear.add_color_stop_rgba(0.65, .1, .1, .1, 1)
linear.add_color_stop_rgba(1.00, outer_color, outer_color, outer_color, 1)
cr.set_source(linear)
cr.arc(x, y, self.radius * .9, 0, 2 * math.pi)
cr.fill()
cr.restore()
def __init__(self):
Gst.init([])
Gtk.init([])
gtk_sink = Gst.ElementFactory.make("gtkglsink")
if (gtk_sink):
sink = Gst.ElementFactory.make("glsinkbin")
sink.set_property("sink", gtk_sink)
gst_gl_widget = gtk_sink.get_property("widget")
pipeline = Gst.Pipeline()
filter = Gst.ElementFactory.make("capsfilter", None)
filter.set_property("caps",
Gst.Caps.from_string("video/x-raw, width=1280, height=720"))
src = Gst.ElementFactory.make("videotestsrc", None)
pipeline.add(src, filter, sink)
src.link(filter)
filter.link(sink)
window = Gtk.Window()
window.connect("delete-event", self.window_closed)
window.connect("key-press-event", self.key_pressed)
window.set_default_size(1280*0.5, 720*0.5)
window.set_title("GtkGLSink Cairo Example")
drawing_area = Gtk.DrawingArea()
drawing_area.add_events(Gdk.EventMask.BUTTON_PRESS_MASK |
Gdk.EventMask.BUTTON_RELEASE_MASK |
Gdk.EventMask.POINTER_MOTION_MASK)
drawing_area.set_size_request(1280, 720)
drawing_area.connect("button-press-event", self.press)
drawing_area.connect("button-release-event", self.press)
drawing_area.connect("motion-notify-event", self.on_motion)
drawing_area.connect("draw", self.on_draw)
overlay = Gtk.Overlay.new ()
overlay.add_overlay(drawing_area)
overlay.add (gst_gl_widget)
window.add (overlay)
window.show_all()
if pipeline.set_state(Gst.State.PLAYING) == Gst.StateChangeReturn.FAILURE:
pipeline.set_state(Gst.State.NULL)
else:
Gtk.main()
if __name__=="__main__":
GtkSinkCairoApp()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment