GTK: проблема с изменением модели TreeView на CellRendererCombo «измененный» сигнал - PullRequest
3 голосов
/ 21 августа 2010

У меня есть вид дерева с CellRendererCombo в данном столбце. Я использую следующий код для настройки столбца:

crc = gtk.CellRendererCombo()
crc.set_property('model', comboModel)
crc.set_property('text-column', 0)
crc.set_property('editable', True)
crc.set_property('has_entry', False)
cl = gtk.TreeViewColumn(ctitle, crc, text=i)

def changed(cell, path, newiter):
    treeViewModel[path][0] = "HAH"
crc.connect("changed", changed)

treeView.append_column(cl)

treeView - это TreeView, treeViewModel - его модель, а comboModel - модель для комбинированной записи, содержащей всего две строки.

Если я запускаю код, то комбо работает должным образом, за исключением того, что при первом выборе записи появляются следующие ошибки:

c:\python25\lib\site-packages\twisted\internet\gtk2reactor.py:255: Warning: inva
lid unclassed pointer in cast to `GObject'
  gtk.main()
c:\python25\lib\site-packages\twisted\internet\gtk2reactor.py:255: Warning: g_ob
ject_notify: assertion `G_IS_OBJECT (object)' failed
  gtk.main()

Во второй раз я получаю:

c:\python25\lib\site-packages\twisted\internet\gtk2reactor.py:255: Warning: inva
lid uninstantiatable type `<invalid>' in cast to `GObject'
  gtk.main()

и в третий раз программа вылетает. Если я изменю соединительную линию на:

crc.connect("edited", changed)

... тогда код работает нормально. Однако значение изменяется только после щелчка вне поля со списком, и я бы предпочел, чтобы оно менялось при каждом выборе объекта. Как я могу сделать последнее?

РЕДАКТИРОВАТЬ: Я только что заметил это в API документы для pygtk :

Обратите внимание, что как только вы измените модель, отображаемую в древовидном представлении, древовидное представление немедленно прекратит операцию редактирования. Это означает, что вы, скорее всего, захотите воздержаться от изменения модели до тех пор, пока средство визуализации комбинированной ячейки не выдаст отредактированный сигнал или edit_canceled.

Это не упоминает, что код потерпит крах, хотя. В любом случае мне бы хотелось, чтобы после нажатия на запись в комбинированном списке редактирование прекращалось без необходимости нажимать клавишу ВВОД или щелкать где-либо еще. Как мне это сделать?

Ответы [ 2 ]

1 голос
/ 05 февраля 2012

Завершение редактирования CellRendererCombo сразу после выбора элемента - это двухэтапный процесс.

На первом этапе вы должны захватить саму комбинацию, поскольку позже она недоступна.Чтобы захватить комбо, подключитесь к сигналу editing-started CellRenderer.Вы можете определить соединение в Glade или создать его вручную в коде.

На втором этапе создайте focus-out-event в обработчике сигнала changed для CellRendererCombo.

Вот ваш оригиналкод, модифицированный для демонстрации:

comboEditable = None

crc = gtk.CellRendererCombo()
crc.set_property('model', comboModel)
crc.set_property('text-column', 0)
crc.set_property('editable', True)
crc.set_property('has_entry', False)
cl = gtk.TreeViewColumn(ctitle, crc, text=i)

def changed(cell, path, newiter):
    treeViewModel[path][0] = "HAH"
    e = gtk.gdk.Event(gtk.gdk.FOCUS_CHANGE)
    e.window = treeView.window
    e.send_event = True
    e.in_ = False
    comboEditable.emit('focus-out-event', e)
def started(cell, editable, path):
    # Or to make life more predictable, use a class and set self.comboEditable
    global comboEditable
    comboEditable = editable
crc.connect('changed', changed)
crc.connect('editing-started', started)

treeView.append_column(cl)

Обратите внимание, что в более поздних версиях GTK + вы обычно не модифицируете TreeModel в обработчике сигнала changed.Вы должны использовать обработчик сигнала edited.

Вот окончательная версия:

comboEditable = None

crc = gtk.CellRendererCombo()
crc.set_property('model', comboModel)
crc.set_property('text-column', 0)
crc.set_property('editable', True)
crc.set_property('has_entry', False)
cl = gtk.TreeViewColumn(ctitle, crc, text=i)

def changed(cell, path, newiter):
    e = gtk.gdk.Event(gtk.gdk.FOCUS_CHANGE)
    e.window = treeView.window
    e.send_event = True
    e.in_ = False
    comboEditable.emit('focus-out-event', e)
def started(cell, editable, path):
    # Or to make life more predictable, use a class and set self.comboEditable
    global comboEditable
    comboEditable = editable
def edited(cell, path, newtext):
    treeViewModel[path][columnNumber] = newText
crc.connect('changed', changed)
crc.connect('editing-started', started)
crc.connect('edited', edited)

treeView.append_column(cl)
0 голосов
/ 22 июня 2011

Я не уверен, но я думаю, что самый быстрый способ получить ответ - поиск в списке рассылки pygtk, и, если вы не можете найти аналогичное сообщение, попробуйте опубликовать его в списке рассылки.

список рассылки pygtk

...