2011-10-05 51 views
3

即時通訊試圖讓拖放在pygobject中很好地工作,但它很慢並且沒有響應,90%的時間我不得不浪費我拖動它的項目,然後才能成功拖放它,任何人都可以看到我是否做得不對,或者這是一個pygobject的bug?這裏是我的代碼在pygobject中無響應的拖放

from gi.repository import Gtk, GdkPixbuf, Gdk 
import os 

def got_data_cb(windowid, context, x, y, data, info, time): 
# Got data. 
tempArray = data.get_text().splitlines() 
for i in tempArray: 
    i = i.replace('file://','') 
    print i 
    windowid.get_model().append([i]) 
context.finish(True, False, time) 

def drop_cb(windowid, context, x, y, time): 
# Some data was dropped, get the data 
windowid.drag_get_data(context, context.list_targets()[-1], time) 
return True 

def main(): 
win = Gtk.Window() 
win.connect('destroy', lambda x: Gtk.main_quit()) 
win.set_default_size(450, 400) 

amodel = Gtk.ListStore(str) 
column = Gtk.TreeViewColumn() 
title = Gtk.CellRendererText() 
column.pack_start(title, True) 
column.add_attribute(title, "text", 0) 
atree = Gtk.TreeView(amodel) 
atree.append_column(column) 

builder = Gtk.Builder() 
filename = os.path.join('', 'treeview.ui') 
builder.add_from_file(filename) 
abox = builder.get_object('treeview1') 

atree.drag_dest_set(0, [], 0) 
atree.connect('drag_motion', lambda v,w,x,y,z: True) 
atree.connect('drag_drop', drop_cb) 
atree.connect('drag_data_received', got_data_cb) 

win.add(atree) 
win.show_all() 

if __name__ == '__main__': 
    Gtk.main() 

main()  

回答

3

因爲我沒有「treeview.ui」文件,你提到的,我口drag'n'drop treeview example of pygtk.

這可能是還就如何轉換舊pygtk的代碼pygi的例子。我只用python3測試這段代碼。

#!/usr/bin/env python 

# example treeviewdnd.py 

from gi.repository import Gtk, Gdk, Pango, GObject 

class TreeViewDnDExample: 

    TARGETS = [ 
     ('MY_TREE_MODEL_ROW', Gtk.TargetFlags.SAME_WIDGET, 0), 
     ('text/plain', 0, 1), 
     ('TEXT', 0, 2), 
     ('STRING', 0, 3), 
     ] 
    # close the window and quit 
    def delete_event(self, widget, event, data=None): 
     Gtk.main_quit() 
     return False 

    def clear_selected(self, button): 
     selection = self.treeview.get_selection() 
     model, iter = selection.get_selected() 
     if iter: 
      model.remove(iter) 
     return 

    def __init__(self): 
     # Create a new window 
     self.window = Gtk.Window() 

     self.window.set_title("URL Cache") 

     self.window.set_size_request(200, 200) 

     self.window.connect("delete_event", self.delete_event) 

     self.scrolledwindow = Gtk.ScrolledWindow() 
     self.vbox = Gtk.VBox() 
     self.hbox = Gtk.HButtonBox() 
     self.vbox.pack_start(self.scrolledwindow, True, True, 0) 
     self.vbox.pack_start(self.hbox, False, True, 0) 
     self.b0 = Gtk.Button('Clear All') 
     self.b1 = Gtk.Button('Clear Selected') 
     self.hbox.pack_start(self.b0, True, True, 0) 
     self.hbox.pack_start(self.b1, True, True, 0) 

     # create a liststore with one string column to use as the model 
     self.liststore = Gtk.ListStore(str) 

     # create the TreeView using liststore 
     self.treeview = Gtk.TreeView(self.liststore) 

     # create a CellRenderer to render the data 
     self.cell = Gtk.CellRendererText() 

     # create the TreeViewColumns to display the data 
     self.tvcolumn = Gtk.TreeViewColumn('URL', self.cell, text=0) 

     # add columns to treeview 
     self.treeview.append_column(self.tvcolumn) 
     self.b0.connect_object('clicked', Gtk.ListStore.clear, self.liststore) 
     self.b1.connect('clicked', self.clear_selected) 
     # make treeview searchable 
     self.treeview.set_search_column(0) 

     # Allow sorting on the column 
     self.tvcolumn.set_sort_column_id(0) 

     # Allow enable drag and drop of rows including row move 
     self.treeview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, 
               self.TARGETS, 
               Gdk.DragAction.DEFAULT| 
               Gdk.DragAction.MOVE) 
     self.treeview.enable_model_drag_dest(self.TARGETS, 
              Gdk.DragAction.DEFAULT) 
     self.treeview.drag_dest_add_text_targets() 
     self.treeview.drag_source_add_text_targets() 

     self.treeview.connect("drag_data_get", self.drag_data_get_data) 
     self.treeview.connect("drag_data_received", 
           self.drag_data_received_data) 

     self.scrolledwindow.add(self.treeview) 
     self.window.add(self.vbox) 
     self.window.show_all() 

    def drag_data_get_data(self, treeview, context, selection, target_id, 
          etime): 
     treeselection = treeview.get_selection() 
     model, iter = treeselection.get_selected() 
     data = bytes(model.get_value(iter, 0), "utf-8") 
     selection.set(selection.get_target(), 8, data) 

    def drag_data_received_data(self, treeview, context, x, y, selection, 
           info, etime): 
     model = treeview.get_model() 
     data = selection.get_data().decode("utf-8") 
     drop_info = treeview.get_dest_row_at_pos(x, y) 
     if drop_info: 
      path, position = drop_info 
      iter = model.get_iter(path) 
      if (position == Gtk.TreeViewDropPosition.BEFORE 
       or position == Gtk.TreeViewDropPosition.BEFORE): 
       model.insert_before(iter, [data]) 
      else: 
       model.insert_after(iter, [data]) 
     else: 
      model.append([data]) 
     if context.get_actions() == Gdk.DragAction.MOVE: 
      context.finish(True, True, etime) 
     return 

def main(): 
    Gtk.main() 

if __name__ == "__main__": 
    treeviewdndex = TreeViewDnDExample() 
    main() 
1

爲了讓我得到拖ñ下降從其他桌面應用程序到我的應用程序的工作,我不得不添加一個drag_motion_callback將數據複製到上下文:

Class Window(Gtk.Window): 
    def __init__(self): 
     #other stuff before here 
     #Set up dragNdrop to add URIs to open draw 
     self.connect("drag-motion", self.motion_cb) 
     self.connect("drag-drop", self.drop_cb) 
     self.connect("drag-data-received", self.got_data_cb) 
     self.drag_dest_set(0, [], 0) 

    def motion_cb(self, wid, context, x, y, time): 
     Gdk.drag_status(context,Gdk.DragAction.COPY, time) 
     # Returning True which means "I accept this data". 
     return True 

    def drop_cb(self, wid, context, x, y, time): 
     wid.drag_get_data(context, context.list_targets()[-1], time) 

    def got_data_cb(self, wid, context, x, y, data, info, time): 
     #Need to do something here 
     files=data.get_text().rstrip('\n').split('\n') 
     for fn in files: 
      fn= fn.split('file://',1)[-1] 
      self.add_file(fn) 
     self.place_items() 
     print files 
     context.finish(True, False, time)