GTK/Python:如何让keypressevent编辑和导航TreeView单元格?

2024-06-26 01:53:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我已连接到“按键事件”以浏览Gtk.TreeView公司. 我成功地让选项卡向右导航(穿过一行)。我无法使用Return向下导航。当单元格再次被选中时,可以再次编辑单元格的内容。我希望行为类似于选项卡,我按一下Return一次,更改被提交,所选单元格下移一个。我想找个电子表格那样的行为。在

我猜这里与键绑定有冲突,即第一个Returnpress事件提交更改,第二个Returnpress事件向下导航。此外,我尝试连接Shift\u L键(而不是Return)向下导航,当它按一下导航时,也无法将更改提交到单元格。在

如果需要的话,我会提出一个MWE,但我认为有人可能知道这里的问题,可以给我指出正确的方向或教育我。在

编辑:好吧,我花时间把所有的东西都简化成了一个可以被任何有能力帮助的人测试/观察的MWE。代码的相关部分是名为onTreeNavigateKeyPress的回调函数。其中,麻烦的条件是elif keyname=='Return'。如果你在你的机器上运行这个程序,你会看到你可以改变单元格的值,右边的制表符选项卡都会向右导航并将更改后的值提交给单元格。使用Return键执行相同操作将提交更改,但您需要再次按Return向下导航。叫我书呆子,但我讨厌这样。从代码中可以看出,我尝试调用Gtk.TreeView.set_光标方法,并从new thread using Glib.timeout_add调用它。在

#!/usr/bin/env python3`

from gi.repository import Gtk, Gdk, GLib


class linFitApp(Gtk.Window):

    def __init__(self):

        Gtk.Window.__init__(self, title='Testing Keypress Events on Treeview')
        self.set_position(Gtk.WindowPosition.CENTER)
        self.set_default_size(400, 300)
        self.set_border_width(5)

        self.mainBox = Gtk.Box()
        self.scrollTableWindow = Gtk.ScrolledWindow()
        self.scrollTableWindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        self.mainBox.pack_start(self.scrollTableWindow, False, False, 0)
        self.add(self.mainBox)

        ############################################################################


        #Now to set up the data table
        self.dataTableListStore = Gtk.ListStore(float, float, float, float)
        self.dataTableTreeView = Gtk.TreeView(model=self.dataTableListStore)
        self.dataTableTreeView.props.activate_on_single_click = True
        self.dataTableTreeView.connect("key-press-event", self.onTreeNavigateKeyPress)

        #set up the x column
        self.xColumnTextRenderer = Gtk.CellRendererText()
        self.xColumnTextRenderer.set_property("editable", True)
        self.xColumnTextRenderer.connect("edited", self.onXChanged)
        self.xColumnTreeView = Gtk.TreeViewColumn("x", self.xColumnTextRenderer, text=0)

        #set up the y column
        self.yColumnTextRenderer = Gtk.CellRendererText()
        self.yColumnTextRenderer.set_property("editable", True)
        self.yColumnTextRenderer.connect("edited",self.onYChanged)
        self.yColumnTreeView = Gtk.TreeViewColumn("y", self.yColumnTextRenderer, text=1)

        #set up the dx column
        self.dxColumnTextRenderer = Gtk.CellRendererText()
        self.dxColumnTextRenderer.set_property("editable", True)
        self.dxColumnTextRenderer.connect("edited",self.onDxChanged)
        self.dxColumnTreeView = Gtk.TreeViewColumn("dx", self.dxColumnTextRenderer, text=2)

        #set up the dy column
        self.dyColumnTextRenderer = Gtk.CellRendererText()
        self.dyColumnTextRenderer.set_property("editable", True)
        self.dyColumnTextRenderer.connect("edited",self.onDyChanged)
        self.dyColumnTreeView = Gtk.TreeViewColumn("dy", self.dyColumnTextRenderer, text=3)

        #pack treeview into the scrolled window
        self.scrollTableWindow.add(self.dataTableTreeView)

        #add treeview columns to treeview
        self.dataTableTreeView.append_column(self.xColumnTreeView)
        self.dataTableTreeView.append_column(self.yColumnTreeView)
        self.dataTableTreeView.append_column(self.dxColumnTreeView)
        self.dataTableTreeView.append_column(self.dyColumnTreeView)

        #fill in treeview with some sample data
        self.dataTableListStore.append([0, 4, 0, 0])
        self.dataTableListStore.append([5, 8.2, 0, 0])
        self.dataTableListStore.append([10, 11.7, 0, 0])
        self.dataTableListStore.append([15, 16.5, 0, 0])
        self.dataTableListStore.append([20, 19, 0, 0])
        self.dataTableListStore.append([25, 24.5, 0, 0])
        self.dataTableListStore.append([30, 26.2, 0, 0])



    #define the callbacks for cell editing
    def onXChanged(self, widget, path, number):
        self.dataTableListStore[path][0]=float(number.replace(',', '.'))

    def onYChanged(self, widget, path, number):
        self.dataTableListStore[path][1]=float(number.replace(',', '.'))

    def onDxChanged(self, widget, path, number):
        self.dataTableListStore[path][2]=float(number.replace(',', '.'))

    def onDyChanged(self, widget, path, number):
        self.dataTableListStore[path][3]=float(number.replace(',', '.'))

    #define the callback for keypress events
    def onTreeNavigateKeyPress(self, treeview, event):
        keyname = Gdk.keyval_name(event.keyval)
        path, col = treeview.get_cursor()
        columns = [c for c in treeview.get_columns()] 
        colnum = columns.index(col)        

        if keyname == 'Tab':

            if colnum + 1 < len(columns):
                next_column = columns[colnum + 1]
            else: 
                next_column = columns[0]
            GLib.timeout_add(50,
                             treeview.set_cursor,
                             path, next_column, True)


        elif keyname == 'Return':

            model = treeview.get_model()
            #Check if currently in last row of Treeview
            if path.get_indices()[0] + 1 == len(model):
                path = treeview.get_path_at_pos(0,0)[0]
                #treeview.set_cursor(path, columns[colnum], True)
                GLib.timeout_add(50,
                             treeview.set_cursor,
                             path, columns[colnum], True)
            else:
                path.next()
                #treeview.set_cursor(path, columns[colnum], True)
                GLib.timeout_add(50,
                             treeview.set_cursor,
                             path, columns[colnum], True)
        else:
            pass


#create main application window and start Gtk loop
mainWindow = linFitApp()
mainWindow.connect("delete-event", Gtk.main_quit)
mainWindow.show_all()
Gtk.main()

Tags: columnsthepathselftruenumbergtkreturn
1条回答
网友
1楼 · 发布于 2024-06-26 01:53:05

答案(也许只是一个功能性的破解)如下:

按下回车键,同时Gtk树景单元格处于编辑模式时不释放按键事件信号。我没有将回调函数连接到按键事件信号,而是将其连接到按键释放事件信号,该信号在编辑单元格时按下Return键后发出。因此,按回车键将激活它所发出的任何一个信号以提交一个新值(我仍然不知道是哪个信号),释放Return键将激活到下一个单元格的导航。喂,按一下回车键,我们就得到了两个想要的动作。在

简短回答:

改变这个

self.dataTableTreeView.connect("key-press-event", self.onTreeNavigateKeyPress)

为了这个

^{pr2}$

相关问题 更多 >