Tkinter mouse event initially triggered

I'm currently learning Tkinter and I cannot find a solution for my problem here nor outside Stackoverflow. In a nutshell, all events that I bind to my widgets are triggered initialy and don't respond to my actions.

In this example, the red rectangle appears on the canvas when I run the code, and

color=random.choice(['red', 'blue'])

revealed that the event binding doesn't work after that:

import Tkinter as tk

class application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.can = tk.Canvas(master, width=200, height=200)
        self.can.bind('<Button-2>', self.draw())
        self.can.grid()
    def draw(self):
        self.can.create_rectangle(50, 50, 100, 100, fill='red')

app = application()
app.mainloop()

I use a Mac platform, but I haven't got a clue about its role in the problem. Could anyone please point me at the mistake i did here?

Answers


There are two things here:

  1. You should not be calling self.draw when you bind it to <Button-2>.

  2. When you click <Button-2>, an event object will be sent to self.draw. Thus, you need to make your function accept this argument, even if it does not use it.

In all, your script should look like this (the lines I changed are in comment boxes):

import Tkinter as tk

class application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.can = tk.Canvas(master, width=200, height=200)
        #######################################
        self.can.bind('<Button-2>', self.draw)
        #######################################
        self.can.grid()
    #######################
    def draw(self, event):
    #######################
        self.can.create_rectangle(50, 50, 100, 100, fill='red')

app = application()
app.mainloop()

There are two mistakes in your code.

1.self.can.bind('<Button-2>', self.draw())

You should not make a method call. You should assign a method which should be called, when Button-2 is clicked

self.can.bind('<Button-2>', self.draw)

2.def draw(self)

Most of the times, an event object will be passed. You should change that line to

def draw(self, event).

In the future, once you are familiar with the basics, you will be using the event object and also learn about why it is getting passed.


Need Your Help

Count column length of data.table, column name is provided from second data.table

r nested data.table

I have a data.table, let's say test.dt, with a column called "id". The rows of column "id" refer to the column headers of a second data.table, say counts.dt. I would like to provide the length of e...

Duplicate title tags using ASP.NET MasterPage

asp.net master-pages title

I need to set the title of a page dynamically, and so I use code similar to the following:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.