2013-08-10 29 views
5

Próbuję znaleźć najprostszy przykład zapisywania niestandardowego widgetu dla Gtk-3.Zapisywanie niestandardowego widgetu przy użyciu GTK3

Do tej pory najlepszą rzeczą jaką znalazłem jest this (używając PyGTK), ale wydaje się, że jest skierowana do Gtk-2.

BTW: Nie obchodzi mnie język, w którym jest napisane, ale jeśli możemy uniknąć C++, znacznie lepiej!

Odpowiedz

0

Oto samouczek dotyczący pisania niestandardowego widgetu kontenera GTK 3 w C: http://ptomato.name/advanced-gtk-techniques/html/custom-container.html Jest to prawdopodobnie bardziej skomplikowane, niż potrzeba do napisania prostego widgetu. Można również zapoznać się z instrukcji migracji z GTK 2 do 3: https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html

+0

to jest z twojego bloga, prawda? kiedy mówisz "To trochę różni się od tego, co działa w GTK 2, i prawdopodobnie istnieje mnóstwo instrukcji GTK 2, które wciąż krążą po Internecie". Polecam, abyś wyraźnie powiedział, że jest to technika GTK 3, aby była bardziej wyraźna. – knocte

+0

i nie jestem pewien, czy mam zamiar oznaczyć tę odpowiedź jako ROZWIĄZANA, ponieważ tak naprawdę nie dostarcza ona próbki, ale dzięki za link – knocte

+0

Racja, nie sądzę, że to również satysfakcjonująco odpowiada na twoje pytanie. :-( – ptomato

11

Python3 Gtk3 tak, to:

from gi.repository import Gtk 

class SuperSimpleWidget(Gtk.Label): 
    __gtype_name__ = 'SuperSimpleWidget' 

Oto nietrywialne przykład, że rzeczywiście coś robi, a mianowicie maluje jego tło i rysuje przez niego ukośną linię. Ja dziedziczenie z Gtk.Misc zamiast Gtk.Widget zaoszczędzić trochę boilerplate (patrz poniżej):

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() 

Wreszcie, jeśli naprawdę chcemy czerpać z Gtk.Widget potem trzeba też założyć tle rysunku. Gtk.Misc robi to za ciebie, ale Gtk.Widget może być kontenerem, który w rzeczywistości niczego nie rysuje. Ale dociekliwych umysły chcą wiedzieć, więc mógłby zrobić to tak:

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) 

Edit i faktycznie go używać:

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() 

Albo, więcej zabawy, użyj go bezpośrednio z ipython3 REPL:

from IPython.lib.inputhook import enable_gtk3 
enable_gtk3() 
w = Gtk.Window() 
w.add(SimpleWidget()) 
w.show_all() 
w.present() 
+0

fajnie! jak uruchomić to za pomocą prostej aplikacji gtk, która ją renderuje? – knocte