[英]GTK Drag-and-drop Validation X11 Cursor lock up within drag_get_data
I have been unable to get drag and drop validation working in pygtk. 我一直无法在pygtk中进行拖放验证。 I am out of ideas and would like a second opinion. 我没有主意,想要第二意见。
My goal is to only allow files which contain .jpg to be dropped. 我的目标是仅允许删除包含.jpg的文件。
Specifically, whenever I call widget.drag_get_data within the drag-motion callback The X11 cursor locks up. 具体来说,每当我在拖动动作回调中调用widget.drag_get_data时,X11光标就会锁定。 Making debugging tedious and aggravating since I have to kill X11 and re launch everything. 由于我不得不杀死X11并重新启动所有程序,因此调试变得乏味且麻烦。
Here is my source code, I think the issue lies specifically in the drag_motion_cb and drag_data_received_cb methods. 这是我的源代码,我认为问题专门出在drag_motion_cb和drag_data_received_cb方法中。 I have left the commented out sections I have tried before. 我已经离开了之前尝试过的注释掉的部分。
Using Google code search searching for drag_get_data doesn't show anyone else doing advanced validation. 使用Google代码搜索搜索drag_get_data不会显示其他人在进行高级验证。 So I'm guessing others failed as well. 所以我想其他人也会失败。
I am out of ideas and will end up just using simple DnD in my linux port (without proper validation) if I cannot figure this out. 我没有主意,如果不能弄清楚的话,最终只会在我的linux端口中使用简单的DnD(没有适当的验证)。
Thanks in advance. 提前致谢。
import pygtk pygtk.require('2.0') import gobject import gtk
TARGET_TEXT_URI_LIST = 0
drop_targets = [ ("text/uri-list", 0, TARGET_TEXT_URI_LIST) ]
class TestApp(gobject.GObject): builder = gtk.Builder() window = None button = None
def init(self): gobject.GObject.init(self)
assert self.builder != None
self.builder.add_from_file("MainWindow.glade");
self.window = self.builder.get_object("window1")
self.button = self.builder.get_object("button1")
self.window.connect("destroy", gtk.main_quit)
self.button.drag_dest_set(gtk.DEST_DEFAULT_ALL, drop_targets, gtk.gdk.ACTION_COPY|gtk.gdk.ACTION_LINK|gtk.gdk.ACTION_MOVE)
self.button.connect("drag-data-received", self.drag_data_received_cb)
self.button.connect("drag-drop", self.drag_drop_cb)
self.button.connect("drag-motion", self.drag_motion_cb)
self.button.connect("drag-leave", self.drag_leave_cb)
self.window.show_all()
drop_data_ready = False drop_occurred = False drop_highlight = False drop_data = None
def drag_data_received_cb(self,widget,context,x,y,data,info,timestamp): print "drag_data_received_cb"
# Check to see if we have the drop data yet.
if False == self.drop_data_ready:
# If this is data we expected or can handle, then process it.
if TARGET_TEXT_URI_LIST == info and data.get_format() == 8 and data.get_length() > 0:
self.drop_data = data.get_uris()
self.drop_data_ready = True
context.drag_status(gtk.gdk.ACTION_COPY, timestamp)
# Actual drop handling code.
if True == self.drop_occurred:
# Reset state.
self.drop_occurred = False
print "RECEIVED DROP",self.drop_data
# Notify whether we handled the drop or not.
context.finish(True,False,timestamp)
# Clean up.
self.drag_leave_cb(widget, context, timestamp)
return True
def drag_drop_cb(self,widget,context,x,y,timestamp): target = widget.drag_dest_find_target(context, widget.drag_dest_get_target_list())
# Is it something we can handle?
if target == gtk.gdk.atom_intern("text/uri-list", False):
# Tell data recieved handler (do_drag_data_received) we can actually handle the drop.
self.drop_occurred = True
widget.drag_get_data(context,target,timestamp)
# We can handle this data type.
return True
else:
# We cannot handle the drop.
return False
pass
def drag_motion_cb(self,widget,context,x,y,timestamp):
if not self.drop_data_ready:
widget.drag_get_data(context, gtk.gdk.atom_intern("text/uri-list",False), timestamp)
return False
"""
target = widget.drag_dest_find_target(context, widget.drag_dest_get_target_list())
if target == gtk.gdk.atom_intern("text/uri-list", False):
if True == self.drop_data_ready:
pass
else:
#widget.drag_get_data(context, target, timestamp)
pass
"""
context.drag_status(gtk.gdk.ACTION_COPY, timestamp)
"""
if target == gtk.gdk.atom_intern("text/uri-list", False):
if True == self.drop_data_ready:
if repr(drop_data).find(".jpg") != -1:
# Tell Gdk we can handle this.
context.drag_status(gtk.gdk.ACTION_COPY, timestamp)
# Draw drop highlight (but only once).
if False == self.drop_highlight:
widget.drag_highlight()
self.drop_highlight = True
# Return here, don't fall through.
return True
else:
# Request drag data from the source.
widget.drag_get_data(context, target, timestamp)
# Fall-through to not allowing.
"""
# not something we can handle
#context.drag_status(0, timestamp) # Don't allow drop.
return True
pass
def drag_leave_cb(self,widget,context,timestamp): # Cleanup drag data. if True == self.drop_data_ready: self.drop_data = None self.drop_data_ready = False
# Un-draw the highlight.
if True == self.drop_highlight:
widget.drag_unhighlight()
self.drop_highlight = False
pass
gobject.type_register(TestApp)
def main(): car = TestApp() gtk.main()
if name == 'main': main()
I think you must do something like this in drag_data_received_cb 我认为您必须在drag_data_received_cb中执行类似的操作
def drag_data_received_cb(self, obj, context, x, y, selection, target_id, etime):
try:
dtype = selection.get_data_type()
except AttributeError:## Old PyGTK
dtype = selection.type
if dtype=='image/jpeg':
image_data = selection.data
## do somthing with image_data
return True
return False
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.