Escribir widget personalizado con GTK3
custom-controls pygtk (3)
Estoy tratando de encontrar el ejemplo más simple de un widget personalizado que se escribe para Gtk-3.
Hasta ahora, lo mejor que he encontrado es esto (usando PyGTK), pero parece estar dirigido a Gtk-2.
Por cierto: no me importa el idioma en el que está escrito, pero si podemos evitar C ++, ¡mucho mejor!
Aquí hay un tutorial sobre cómo escribir un widget de contenedor personalizado GTK 3 en C: http://ptomato.name/advanced-gtk-techniques/html/custom-container.html Probablemente sea más complicado de lo que necesita para escribir un widget simple. También puede consultar la guía de migración de GTK 2 a 3: https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html
Python3 Gtk3 es, entonces:
from gi.repository import Gtk
class SuperSimpleWidget(Gtk.Label):
__gtype_name__ = ''SuperSimpleWidget''
Aquí hay un ejemplo no trivial que realmente hace algo, es decir, pinta su fondo y dibuja una línea diagonal a través de él. Estoy heredando de Gtk.Misc
lugar de Gtk.Widget
para guardar algunas repeticiones (ver a continuación):
class SimpleWidget(Gtk.Misc):
__gtype_name__ = ''SimpleWidget''
def __init__(self, *args, **kwds):
super().__init__(*args, **kwds)
self.set_size_request(40, 40)
def do_draw(self, cr):
# paint background
bg_color = self.get_style_context().get_background_color(Gtk.StateFlags.NORMAL)
cr.set_source_rgba(*list(bg_color))
cr.paint()
# draw a diagonal line
allocation = self.get_allocation()
fg_color = self.get_style_context().get_color(Gtk.StateFlags.NORMAL)
cr.set_source_rgba(*list(fg_color));
cr.set_line_width(2)
cr.move_to(0, 0) # top left of the widget
cr.line_to(allocation.width, allocation.height)
cr.stroke()
Finalmente, si realmente quieres derivar de Gtk.Widget
entonces también debes configurar un fondo de dibujo. Gtk.Misc
hace eso por usted, pero Gtk.Widget
podría ser un contenedor que en realidad no dibuje nada. Pero las mentes inquisitivas quieren saber, para que puedas hacerlo así:
from gi.repository import Gdk
class ManualWidget(Gtk.Widget):
__gtype_name__ = ''ManualWidget''
def __init__(self, *args, **kwds):
# same as above
def do_draw(self, cr):
# same as above
def do_realize(self):
allocation = self.get_allocation()
attr = Gdk.WindowAttr()
attr.window_type = Gdk.WindowType.CHILD
attr.x = allocation.x
attr.y = allocation.y
attr.width = allocation.width
attr.height = allocation.height
attr.visual = self.get_visual()
attr.event_mask = self.get_events() | Gdk.EventMask.EXPOSURE_MASK
WAT = Gdk.WindowAttributesType
mask = WAT.X | WAT.Y | WAT.VISUAL
window = Gdk.Window(self.get_parent_window(), attr, mask);
self.set_window(window)
self.register_window(window)
self.set_realized(True)
window.set_background_pattern(None)
Editar y usarlo realmente:
w = Gtk.Window()
w.add(SimpleWidget())
w.show_all()
w.present()
import signal # enable Ctrl-C since there is no menu to quit
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
O, más divertido, utilícelo directamente de ipython3 REPL:
from IPython.lib.inputhook import enable_gtk3
enable_gtk3()
w = Gtk.Window()
w.add(SimpleWidget())
w.show_all()
w.present()
Hasta ahora, la mejor referencia para:
- comprender Gobject (del que deriva el widget gtk)
- tener un código de caldera y un código c
https://developer.gnome.org/gobject/stable/howto-gobject.html
Sé que no está escrito en Python, pero convertir de c a python es pan comido (lo que importa es el algoritmo, no el lenguaje)