Собственный значок перетаскивания с такими же настройками цвета и шрифта, что и у значка перетаскивания по умолчанию в Gtk.TreeView - PullRequest
0 голосов
/ 15 сентября 2018

Gtk.TreeView реализует значок перетаскивания по умолчанию.Он использует цвет фона TreeView, его шрифт и весь контент строки в виде строки.

Я хочу то же самое (цвет фона, font-face, font-size, font-color) но с более короткой строкой (только второй из трех столбцов).

В приведенном ниже примере создайте мой собственный cairo.Surface для создания такой иконки.Но цвет и шрифт это проблема.Я не знаю, как их настроить или (что гораздо важнее) запросить у TreeView или Gtk текущие значения цвета и шрифта.

Как TreeView получает эти значения?

#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
import cairo

class MainWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="TreeView Drag and Drop")
        self.connect("delete-event", Gtk.main_quit)
        self.box = Gtk.Box()
        self.add(self.box)

        # "model" with dummy data
        self.store = Gtk.TreeStore(int, str, int)
        for i in range(5):
            self.store.append(None, [i, 'Item {}'.format(i), i]) # treeview
        self.tree = Gtk.TreeView(model=self.store)
        self.box.pack_start(self.tree, True, True, 0)

        # build columns
        colA = Gtk.TreeViewColumn('Col A', Gtk.CellRendererText(), text=0)
        self.tree.append_column(colA)
        colB = Gtk.TreeViewColumn('Col B', Gtk.CellRendererText(), text=1)
        self.tree.append_column(colB)
        colC = Gtk.TreeViewColumn('Col C', Gtk.CellRendererText(), text=2)
        self.tree.append_column(colC)

        # enable default drag and drop
        self.tree.set_reorderable(True)

        # DnD events
        self.tree.connect_after("drag-begin", self.drag_begin)

    def drag_begin(self, widget, context):
        model, path = widget.get_selection().get_selected_rows()
        text = model[path][1]

        # dummy surface/context
        surface = cairo.ImageSurface(cairo.Format.RGB24, 0, 0)
        cr = cairo.Context(surface)

        # calculate text size
        txtext = cr.text_extents(text)
        width = int(txtext.width)
        height = int(txtext.height)
        offset = 10

        # creal surface/context
        surface = cairo.ImageSurface(cairo.Format.RGB24,
                                     width + (offset*2),
                                     height + (offset*2))
        cr = cairo.Context(surface)
        cr.set_source_rgb(1, 1, 1) # text color: white
        cr.move_to(0+offset, height+offset)
        cr.show_text(text)

        # use the surface as drag icon
        Gtk.drag_set_icon_surface(context, surface)

win = MainWindow()
win.show_all()
Gtk.main()

Я пытался (но не работал): cairo.Surface.create_similar()', cairo.Surface.create_s Similar_image () and Gtk.TreeView.create_row_drag_icon () `.

1 Ответ

0 голосов
/ 15 сентября 2018

Этот ответ основан на размещении иностранной рассылки .

widget имеет Gtk.StyleContext. A Pango.Layout используется для визуализации текста на основе информации о стиле в Gtk.StyleContext.

def drag_begin(self, widget, context):
    model, path = widget.get_selection().get_selected_rows()
    text = model[path][1]

    stylecontext = widget.get_style_context()

    # new pango layout
    pl = widget.create_pango_layout(text)
    ink_rec, log_rect = pl.get_pixel_extents()
    padding = 5 

    # create surface/context
    surface = cairo.ImageSurface(cairo.Format.RGB24,
                                 log_rect.width + (padding*2),
                                 log_rect.height + (padding*2))
    cr = cairo.Context(surface)
    Gtk.render_background(stylecontext, cr, 0, 0,
                          log_rect.width + (padding*2),
                          log_rect.height + (padding*2))
    Gtk.render_layout(stylecontext, cr, padding, padding, pl)

    # border
    line_width = cr.get_line_width()
    cr.rectangle(-1+line_width, -1+line_width,
                 log_rect.width+(padding*2)-line_width,
                 log_rect.height+(padding*2)-line_width)
    cr.stroke()

    # use the surface as drag icon
    Gtk.drag_set_icon_surface(context, surface)
...