【问题标题】:unresponsive drag and drop in pygobjectpygobject中无响应的拖放
【发布时间】:2011-10-05 12:04:33
【问题描述】:

我试图让拖放在 pygobject 中运行良好,但它很慢且反应迟钝,90% 的时间我必须挥动我正在拖动的项目才能成功放下它,任何人都可以看到我是否做错了还是这是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()    

【问题讨论】:

    标签: python introspection pygobject gtk3


    【解决方案1】:

    因为我没有你引用的“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()
    

    【讨论】:

      【解决方案2】:

      为了让我从另一个桌面应用程序拖放到我的应用程序,我必须添加一个 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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-23
        • 1970-01-01
        • 2015-12-21
        • 2018-07-06
        • 2012-02-04
        相关资源
        最近更新 更多