Tkinter: How to bind an event that repeats if continued to be selected

Matthew Dixon Cowles matt at mondoinfo.com
Thu Jan 10 04:35:24 CET 2002


On Tue, 8 Jan 2002 14:00:17 +0000, Martyn Quick
<mrq at for.mat.bham.ac.uk> wrote:

Dear Martyn,

>Hi All!

Hi!

>The following appears to be a bit difficult, but probably it isn't if
>you are an expert.

I doubt that I qualify as an expert but I've done similar things
before.

>I've created a `counter'-like widget as shown below.  Basically if
>you click on the arrow button it increases the value displayed in the
>entry.

>My question is what do I have to change in the bindings to make it
>behave slightly differently, namely if you click on the arrow button
>and hold, then after a while it begins to automatically increase
>(i.e., repeatedly call self.increment until you release?

All that needs to be added are a few judicious calls to after() and a
flag. I'll append a slightly-modified version of your code.

Regards,
Matt



import Pmw, Tkinter


class Counter(Pmw.MegaWidget):
    initDelay=750 # ms
    repeatDelay=500

    def __init__(self, parent=None):
        Pmw.MegaWidget.__init__(self, parent)
        self.mouseStillDown=0
        interior = self.interior()
        self.var = Tkinter.IntVar()
        self.createcomponent(
            'entry', (), None, Tkinter.Entry, (interior,),
            state='disabled', textvariable=self.var,
            width=5).pack(side='left')
        self.arrow = self.createcomponent(
            'arrow', (), None, Tkinter.Canvas, (interior,), width=16,
            height=16, relief='raised', borderwidth=1)
        self.arrow.pack()
        Pmw.drawarrow(self.arrow, 'black', 'up', 'arrow')
        self.arrow.bind('<1>', self.click)
        self.arrow.bind('<ButtonRelease-1>', self.release)

    def click(self,event):
        self.mouseStillDown=1
        self.increment()
        # Could send the after() to any widget
        self.arrow.after(self.initDelay,self.maybeIncrementAgain)
      
    def increment(self):
        self.arrow.config(relief='sunken')
        self.var.set(self.var.get()+1)

    def release(self, event):
        self.mouseStillDown=0
        self.arrow.config(relief='raised')
        
    def maybeIncrementAgain(self):
        if self.mouseStillDown:
            self.increment()
            self.arrow.after(self.repeatDelay,self.maybeIncrementAgain)

def main():
  root=Tkinter.Tk()
  Pmw.initialise(root)
  c=Counter(root)
  c.pack()
  root.mainloop()
  
if __name__=="__main__":
  main()



More information about the Python-list mailing list