I'm confused as to how I would implement a drag and drop ability for a window and then have the url appear in the textbox.
I've updated where I am stuck at
class controller(NSWindow):
#File to encode or decode
form_file = IBOutlet()
mainWindow = IBOutlet()
#drag and drop ability
def awakeFromNib(self):
self.registerForDraggedTypes_([NSFilenamesPboardType, None])
print 'registerd drag type'
def draggingEntered_(self, sender):
print 'dragging entered doctor who'
pboard = sender.draggingPasteboard()
types = pboard.types()
opType = NSDragOperationNone
if NSFilenamesPboardType in types:
opType = NSDragOperationCopy
return opType
def performDragOperation_(self,sender):
print 'preform drag operation'
pboard = sender.draggingPasteboard()
successful = False
if NSFilenamesPboardType in pboard.types():
print 'my actions finally working'
fileAStr = pboard.propertyListForType_(NSFilenamesPboardType)[0]
print type(fileAStr.encode('utf-8'))
successful = True
print self.form_file
return successful
I can drop the file but I am unable to refrence the form_file
outlet from inside of the performDragOperation
function. As you can see I am attempting to print it but it returns a NoneType
error.
(reason '<type 'exceptions.TypeError'>: 'NoneType' object is not callable') was raised during a dragging session
I believe your problem here was that something earlier in the Responder Chain was handling -[draggingEntered:]
and rejecting the drag, before your window could get to it.
For a typical AppKit app, before getting to the window, an action message goes to the First Responder from the NIB, and anything hooked onto the back of it, then the innermost view and its delegate, then all of its ancestor views and their delegates. So if, for example, you have a text edit view that handles drag messages, and you drag over that view, the window won't see it.
Anyway, there are lots of ways to debug this, but the simplest one is to just have each method iterate the nextResponder()
chain from self
, print
ing (or logging.log
ging or NSLog
ging) the result. Then you can see who you're blocking.
Since there were a bunch of other issues we talked about in the comments, I'm not sure if this was the one that actually solved your problem. But one thing in particular to bring up:
I don't think PyObjC was part of the problem here. When the Cocoa runtime sends an ObjC message like -[draggingEntered:]
to a PyObjC object, the PyObjC runtime handles that by looking for a draggingEntered_
method and converting it magically. (Well, I say magic, but it's simple science. Also, because it's sonic, it doesn't do wood.) You need @IBAction
in the same places an ObjC program would need (IBAction)
, which are documented pretty well in the Cocoa documentation.
Meanwhile, one general-purpose debugging tip for PyObjC code (or just about any other event-loop-based or otherwise non-linear code). When you get an error like this:
(reason '<type 'exceptions.TypeError'>: 'NoneType' object is not callable') was raised during a dragging session
It's hard to figure out what exactly went wrong. But you can handle the exception inside the function that raised, and get all the information you want. You can wrap a try
/except
around each line to figure out which line raised, you can print
the whole traceback instead of just the summary, etc.