[英]gtk.TreeView does not change after changing its gtk.ListStore:
[英]Synchoronize editable Gtk.TreeView with its ListStore
我正在使用Glade在Gtk3 / Python3中构建一个接口,在TreeView中显示来自ListStore的数据,并允许用户编辑其中一列中的值。
如前所述,我正在使用林间空地,并且在林间空地文件中写入了哪个ListStore
每个GtkCellRenderer
提供哪些数据。 第一个有趣的事情是我不知道如何获取此信息,并且我正在引入冗余以使事情正常进行。
下一个更有趣的麻烦:当一个已编辑的单元格失去焦点,但焦点仍停留在TreeView中时,将调用我对已edited
信号的回调,并将已编辑的值存储在ListStore中。
当一个已编辑的单元格失去焦点,并且焦点转到另一个小部件时(如示例中另一个无用的Button一样),则不会调用已注册的回调。 同样,如果窗口失去焦点,则将恢复先前的值。 在“焦点跟随鼠标”的情况下,最后一个特别不切实际。
这是怎么回事?
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
class TestWindow:
def __init__(self, builder):
import os.path
path, name = os.path.split(__file__)
builder.add_from_file(os.path.join(path, "treeedit.glade"))
builder.connect_signals(self)
self.window = builder.get_object("window1")
self.window.connect("destroy", Gtk.main_quit)
self.notes_list = builder.get_object("notes_list")
self.notes_list.append(('a',))
self.notes_list.append(('b',))
self.notes_list.append(('c',))
self.notes_list.append(('d',))
def on_cell_edited(self, widget, path, text):
self.notes_list[path][0] = text
def show_all(self):
self.window.show_all()
builder = Gtk.Builder()
win = TestWindow(builder)
win.show_all()
Gtk.main()
这是林间空地文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkListStore" id="notes_list">
<columns>
<!-- column-name content -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkDialog" id="window1">
<property name="can_focus">False</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">button</property>
</object>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<child>
<object class="GtkAlignment">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkTreeView" id="notes_tree">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="model">notes_list</property>
<property name="headers_clickable">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
<child>
<object class="GtkTreeViewColumn">
<property name="resizable">True</property>
<property name="title" translatable="yes">value</property>
<child>
<object class="GtkCellRendererText" id="prefs_cellrenderertext1">
<property name="editable">True</property>
<signal name="edited" handler="on_cell_edited" swapped="no"/>
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Notes</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
我自己的答案只是部分答案,因为如果我需要编辑多列怎么办? 截至目前,我已经诉诸于将多个回调写入到editing-started
信号中,如下所示:
def on_cell_editing_started_col0(self, *args):
self.column = 0
def on_cell_editing_started_col1(self, *args):
self.column = 1
然后我在两个回调中都使用self.column
值,分别用于Gtk.CellRendererText
edited
信号和Gtk.TreeView
set-focus-child
信号。
看来我可以为容器TreeView
的信号set-focus-child
注册一个回调。 当可编辑的子项开始被编辑时,以及编辑完成时,将调用此方法。 在这两种情况下,回调都接收两个参数,第一个是TreeView
本身。
当编辑开始时,第二个参数是用户与之交互的临时Gtk.Entry
。 编辑结束后,第二个参数为None
。
我可能会使用此代码,而且我确定我不知道这可能有多强大:
def on_focus_child(self, tree, entry):
if entry is not None:
self.last_entry = entry
else:
tv, path = tree.get_selection().get_selected()
self.notes_list[path][0] = self.last_entry.get_text()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.