2011-06-21 7 views
14

में बाध्यकारी कैसे मैं कार्रवाई की जा रही से एक घटना को रोकने या स्विच कर सकता क्या समारोह इसके लिए कहा जाता है एक tkinter घटना बदल रहा है?हटाया जा रहा है और अजगर

संशोधित कोड:

from Tkinter import * 

class GUI: 
    def __init__(self,root): 
     Window = Frame(root) 
     self.DrawArea = Canvas(Window) 
     self.DrawArea.pack() 
     Window.pack() 

     self.DrawArea.bind("<Button 1>",self.starttracking) 

    def updatetracking(self,event): 
     print event.x,event.y 

    def finishtracking(self,event): 
     self.DrawArea.bind("<Button 1>",self.starttracking) 
     self.DrawArea.unbind("<Motion>") 

    def starttracking(self,event): 
     print event.x,event.y 
     self.DrawArea.bind("<Motion>",self.updatetracking) 
     self.DrawArea.bind("<Button 1>",self.finishtracking) 



if __name__ == '__main__': 
    root = Tk() 
    App = GUI(root) 
    root.mainloop() 

उत्तर

25

आप बस सिर्फ bind() फिर घटना के लिए नए कार्य के साथ कह सकते हैं। चूंकि आप तीसरे पैरामीटर का उपयोग नहीं कर रहे हैं, add, bind() में यह केवल पहले से मौजूद कुछ भी ओवरराइट करेगा। डिफ़ॉल्ट रूप से इस पैरामीटर '' है लेकिन यह भी "+" है, जो पहले से ही कॉलबैक है कि घटना से चालू होने के लिए एक कॉलबैक जोड़ देगा स्वीकार करता है।

आपको लगता है कि वैकल्पिक तर्क का उपयोग हालांकि आप अलग-अलग कॉलबैक दूर करने के लिए unbind() फ़ंक्शन का उपयोग करने की आवश्यकता होगी शुरू करते हैं। जब आप bind() पर कॉल करते हैं तो funcid वापस आ जाता है। आप unbind() पर दूसरे पैरामीटर के रूप में इस funcid को पास कर सकते हैं।

उदाहरण:

self.btn_funcid = self.DrawArea.bind("<Button 1>", self.my_button_callback, "+") 

# Then some time later, to remove just the 'my_button_callback': 
self.DrawArea.unbind("<Button 1>", self.btn_funcid) 

# But if you want to remove all of the callbacks for the event: 
self.DrawArea.unbind("<Button 1>") 
4

मेरे लिए, अनबाइंडिंग एक भी कॉलबैक काम नहीं कर रहा था, लेकिन मैं एक समाधान मिल गया।

मैं देख सकता हूँ यह एक पुराने सवाल है, लेकिन उन जब एक ही समस्या का सामना करना पड़ जो, अपने आप की तरह, इस सवाल को खोजने के लिए, यह क्या मैं इसे काम करने के लिए किया था।

आपको स्रोत फ़ाइल Tkinter.py खोलने और विविध वर्ग की अनबिंड विधि की खोज करने की आवश्यकता होगी (यदि आप ग्रहण का उपयोग कर रहे हैं तो फ़ाइल के स्थान को जानना आसान है और जिस पंक्ति में यह फ़ंक्शन दबाने से परिभाषित किया गया है F3 कुंजी जब कर्सर आपके कोड में .unbind फ़ंक्शन कॉल पर है)।

जब आप इसे खोजने के लिए, आप कुछ इस तरह देखना चाहिए:

def unbind(self, sequence, funcid=None): 
     """Unbind for this widget for event SEQUENCE the 
     function identified with FUNCID.""" 
     self.tk.call('bind', self._w, sequence, '') 
     if funcid: 
      self.deletecommand(funcid) 

आप इसे बदलने के लिए इस तरह somethins देखने की जरूरत है:

def unbind(self, sequence, funcid=None): 
     """Unbind for this widget for event SEQUENCE the 
     function identified with FUNCID.""" 
    if not funcid: 
     self.tk.call('bind', self._w, sequence, '') 
     return 
    func_callbacks = self.tk.call('bind', self._w, sequence, None).split('\n') 
    new_callbacks = [l for l in func_callbacks if l[6:6 + len(funcid)] != funcid] 
    self.tk.call('bind', self._w, sequence, '\n'.join(new_callbacks)) 
    self.deletecommand(funcid) 

कि चाल करना चाहिए!

+0

मुझे भी अनबिंड के साथ porblems था! आपको परिवर्तनों को विलय करना चाहिए! – timeyyy

+0

@arcra: उबंटू 16.10 पर पायथन 3.5.2 चल रहा है और अभी भी वही समस्या है जिसे आपने तय किया है। आपका समाधान अभी भी पूरी तरह से काम करता है क्योंकि स्रोत अभी तक पैच नहीं किया गया है। आर्डेन की तरह मैं सुझाव देता हूं कि आप क्रेडिट प्राप्त करने के लिए इसका प्रस्ताव दें और इसे निश्चित रूप से लागू करें। –

4

ब्रायन द्वारा प्रदान की जवाब आम तौर पर अच्छी तरह से काम करता है, लेकिन जैसा कि arcra को रेखांकित किया गया है, यह नहीं हो सकता है। यदि आपको एक स्टैक्ड कॉलबैक को सही ढंग से अनबाइंड करने में सक्षम नहीं होने की समस्या का अनुभव होता है, तो आधिकारिक स्रोत को संशोधित करना - यदि यह अभी भी वही है! - एक समाधान हो सकता है।

यहाँ जो लोग अभी भी खुद को समस्या से अटक को खोजने के लिए मेरे 2 सेंट का पालन करें: कृपया, ओवरराइड अनबाइंड() विधि, यह सीधे संपादित न करें।

इस तरह, वास्तव में, आपको अपने वर्कस्टेशन पर आधिकारिक स्रोत कोड मैन्युअल रूप से बदलने की आवश्यकता नहीं है (इस प्रकार पैकेज प्रबंधन को तोड़ना, या अगले पैकेज अपडेट पर समस्या को पुन: प्रस्तुत करना, या किसी अन्य क्लाइंट पर एक ही समस्या होनी चाहिए, ...):

import tkinter as tk 


class PatchedCanvas(tk.Canvas): 
    def unbind(self, sequence, funcid=None): 
     ''' 
     See: 
      http://stackoverflow.com/questions/6433369/ 
      deleting-and-changing-a-tkinter-event-binding-in-python 
     ''' 

     if not funcid: 
      self.tk.call('bind', self._w, sequence, '') 
      return 
     func_callbacks = self.tk.call(
      'bind', self._w, sequence, None).split('\n') 
     new_callbacks = [ 
      l for l in func_callbacks if l[6:6 + len(funcid)] != funcid] 
     self.tk.call('bind', self._w, sequence, '\n'.join(new_callbacks)) 
     self.deletecommand(funcid) 

फिर, मेरे उदाहरण में अपने असफल रहने विजेट (instantiating के बजाय मैं इस

myCanvas = tk.Canvas(...) 

तरह कैनवास) का उपयोग आप बस इसे अपने समझौता संस्करण से दृष्टांत होगा कि एक अद्यतन यदि आवश्यकता होगी ,

myCanvas = PatchedCanvas(...) 

अनबाइंड विधि वर्तमान में विविध वर्ग, जिसमें से BaseWidget यह विरासत में परिभाषित किया गया है और फिर conseq: और केवल यदि आधिकारिक स्रोत अद्यतन किया जाएगा और तय यूटी, विजेट, टॉपलेवल, बटन, ...

+0

बहुत बहुत धन्यवाद! मुझे इसकी ज़रूरत है! –