Выделите только некоторые строки жирным шрифтом в Gtk.TreeView

Я хочу отобразить статус читать или непрочитанный строки, сделав текст (столбца в строке) смелый или нет.

Статус строки (или данных в модели) может быть частью модели или где-то еще. Я гибок в этом вопросе.

Как сделать текст конкретной ячейки полужирным в зависимости от базовых (динамических) данных, которыми в этом примере является значение 1?

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

class View(Gtk.TreeView):
    def __init__(self, model):
        Gtk.TreeView.__init__(self, model)
        col = Gtk.TreeViewColumn('Text',
                                 Gtk.CellRendererText(),
                                 text=0)
        self.append_column(col)
        # bold text
        # Gtk.CellRendererText(weight_set=True, weight=700),


class Model(Gtk.ListStore):
    def __init__(self):
        Gtk.ListStore.__init__(self, str, int)
        self.append(['foo 1', 0])
        self.append(['foo 2', 1])  # bold
        self.append(['foo 3', 0])
        self.append(['foo 4', 0])
        self.append(['foo 5', 1])  # bold

class Window(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.set_default_size(100, 200)

        # model & view
        self.model = Model()
        self.view = View(self.model)

        # layout
        self.layout = Gtk.Grid()
        self.add(self.layout)
        self.layout.attach(self.view, 0, 0, 1, 2)

        self.connect('destroy', Gtk.main_quit)
        self.show_all()

if __name__ == '__main__':
    win = Window()
    Gtk.main()

Вы спрашиваете, как сделать текст жирным?

Azsgy 14.04.2018 23:58

@Azsgy Это часть вопроса. Я не хочу выделять жирным шрифтом все строки - только некоторые из них, в зависимости от данных.

buhtz 15.04.2018 00:04

Между прочим, отличный вопрос потребовал времени, чтобы разобраться в нем. Сегодня тоже кое-что узнал.

Azsgy 15.04.2018 01:35
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
3
622
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Как это часто бывает в Gtk, это очень просто, но не очень очевидно. Вам действительно нужно знать, где искать, и внимательно читать соответствующие документы.

class View(Gtk.TreeView):
    def __init__(self, model):
        Gtk.TreeView.__init__(self, model)
        renderer = Gtk.CellRendererText()
        col = Gtk.TreeViewColumn(
            'Text', renderer, text=0, weight_set=True)
        col.set_cell_data_func(renderer, datafunc)
        self.append_column(col)

Первый ключ - это TreeViewColumn.set_cell_data_funcметод. Это позволяет вам установить функцию перехвата, которую вы можете использовать для изменения свойств ячейки перед ее визуализацией. Вот пример, который я написал, который делает то, что вы хотите:

def datafunc(col, renderer, model, titer, data):
    val = model.get_value(titer, 1)

    if val:
        renderer.set_property("weight", 700)

Как вы можете видеть, он получает задействованные TreeViewColumn, CellRenderer, TreeModel и TreeIter, а также пользовательские данные, которые я исключил.

Первый шаг - получить значения текущего столбца. Для этого мы даем модели treeiter (который сохраняет «текущую строку», вроде как) и идентификатор столбца, который нам нужен (в данном случае второй столбец, 1).

Остальное довольно просто, мы используем это значение, чтобы решить, нужно ли нам устанавливать свойство «вес» в CellRenderer.

Здесь вы использовали 700, но для ясности я бы порекомендовал вам использовать Pango.Weight.BOLD. Конечно, для этого требуется from gi.repository import Pango.

Ответ принят как подходящий

После короткого обсуждения с сопровождающими Gtk я обнаружил, что есть другой, более чистый способ сделать это. Поскольку оба ответа работают, я решил выделить это как отдельный ответ.

Проблема с другим ответом заключается в том, что cell_data_func вызывается для каждой строки. Со временем это станет очень медленным, если у вас много строк.

Решение здесь - добавить еще один столбец в вашу модель, который вы затем привяжете к соответствующему атрибуту (ам).

В настоящее время вы делаете следующее:

col = Gtk.TreeViewColumn(
            'Text', renderer, text=0, weight_set=True)

Это связывает свойство textCellRenderer со столбцом 0 вашей модели.

Теперь мы можем привязать это и к любому другому свойству. Например, привяжите столбец 1 к свойству weight:

col = Gtk.TreeViewColumn(
            'Text', renderer, text=0, weight=1, weight_set=True)

Затем вы можете установить в этом столбце различные значения Pango.Weight, чтобы изменить вес текста.

class Model(Gtk.ListStore):
    def __init__(self):
        ...
        self.append(['foo 1', Pango.Weight.BOLD])
        self.append(['foo 2', Pango.Weight.BOOK])
        ...

Если вы хотите установить дополнительные свойства, вы также можете установить свойство markup (которое анализирует строку как разметку панго и позволяет вам изменять шрифт, цвет и т. д. Некоторых частей текста) и свойство attributes, которое вы можете использовать для одновременной установки множества атрибутов стиля с типом pango.AttrList.

Большое спасибо за подробный ответ. А вот этот (без cell_data_fund) я не понимаю.

buhtz 15.04.2018 08:12

Понятно. «Привязка свойства к столбцу» означает: значения свойств сохраняются в модели и считываются оттуда. Верно?

buhtz 15.04.2018 13:04

@buhtz Ага, именно так. Эту концепцию сложно понять.

Azsgy 15.04.2018 13:17

Другие вопросы по теме