使用GTK3编写自定义小部件

kno*_*cte 7 gtk pygtk widget custom-controls

我试图找到为Gtk-3编写的自定义小部件的最简单示例.

到目前为止,我已经找到了最好的事情是这个(使用PyGTK的),但它似乎有针对性地GTK的2.

顺便说一句:我不关心它所用的语言,但如果我们能避免使用C++,那就更好了!

vbr*_*aun 12

它是Python3 Gtk3,然后:

from gi.repository import Gtk

class SuperSimpleWidget(Gtk.Label):
    __gtype_name__ = 'SuperSimpleWidget'
Run Code Online (Sandbox Code Playgroud)

这是一个非常重要的例子,它实际上做了一些事情,即绘制背景并在其中绘制对角线.我继承Gtk.Misc而不是Gtk.Widget保存一些样板(见下文):

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()
Run Code Online (Sandbox Code Playgroud)

最后,如果你真的想从中衍生出来,Gtk.Widget你还必须设置一个绘图背景.Gtk.Misc这样做对你来说,但Gtk.Widget可能是一个实际上并没有自己绘制任何东西的容器.但是询问的头脑想要知道,所以你可以这样做:

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)
Run Code Online (Sandbox Code Playgroud)

编辑并实际使用它:

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()
Run Code Online (Sandbox Code Playgroud)

或者,更有趣,直接从ipython3 REPL使用它:

from IPython.lib.inputhook import enable_gtk3
enable_gtk3()
w = Gtk.Window()
w.add(SimpleWidget())
w.show_all()
w.present()
Run Code Online (Sandbox Code Playgroud)


pto*_*ato 0

以下是关于用 C 语言编写 GTK 3 自定义容器小部件的教程: http: //ptomato.name/advanced-gtk-techniques/html/custom-container.html它可能比编写简单小部件所需的更复杂。您还可以查看从 GTK 2 到 3 的迁移指南:https://developer.gnome.org/gtk3/stable/gtk-migration-2-to-3.html