widget gtk custom-controls pygtk

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!



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)