簡體   English   中英

與可編輯的Gtk.TreeView及其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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM