2015-11-11 21 views
3

我已連接到「按鍵事件」以瀏覽Gtk.TreeView。我成功獲得標籤導航到右側(橫跨一行)。我在使用返回向下導航時遇到問題。當選中一個單元格時,我可以編輯它的內容,但我必須按返回一次提交該值並再次導航到下面的單元格。我希望行爲類似於標籤,其中我按返回一次,並且提交更改並且所選單元格向下移動一個。我喜歡電子表格的行爲。GTK/Python:如何讓按鍵事件編輯和導航TreeView單元格?

我猜有衝突這裏的鍵綁定,即,第一返回新聞發佈會上提交更改和第二返回新聞發佈會上向下導航。此外,我試圖連接Shift_L鍵(而不是返回)向下導航,並且在導航時按一下它也無法將更改提交到單元格。

如果需要的話,我會調出一個MWE,但我認爲這裏有人可能知道這個問題,並可能指向正確的方向或教育我。

編輯:好的,我花了一些時間,把所有東西都剝下來,以便能夠幫助任何人進行測試/眼科檢查。代碼的相關部分是名爲的onTreeNavigateKey按的回調函數。在那之內,麻煩的條件是elif keyname =='返回'。如果你在你的機器上運行它,你會看到你可以改變單元格值,並且標籤向右,而標籤都向右導航,並將改變的值提交給單元格。這樣做與返回鍵將提交更改,但您需要再次按返回向下導航。叫我迂腐,但我討厭那個。從代碼中可以看到,我嘗試直接使用新位置調用Gtk.TreeView.set_cursor方法,並從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() 
+0

UPDATE:我把打印語句轉換成映入返回按鍵的回調函數,它看起來像我只捕獲每第二次按鍵。將值提交給單元的按鍵不會發出*按鍵事件*信號。該怎麼辦... – wrkyle

回答

1

答案(也許只是一個功能性的黑客)如下:

按回車鍵而Gtk.Treeview細胞是在編輯模式下不釋放按鍵事件信號。取代將我的回撥功能連接到按鍵事件信號,我將其連接到按鍵釋放事件信號,其中在編輯單元格時按下Return鍵後發出。所以按下回車鍵將激活它提交新值的任何信號(我仍然不知道是哪個信號),然後釋放回車鍵將激活導航到下一個單元格。瞧,我們有兩個想要的行動,只需按下一次返回鍵。

簡短的回答:

更改此

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

這個

self.dataTableTreeView.connect("key-release-event", self.onTreeNavigateKeyPress) 
相關問題