Skip to content Skip to sidebar Skip to footer

Tkinter / Ttk - Prevent String To Buttonpress Conversion

I'm writing a simple script that creates a ttk Treeview (that acts as a table) and, when you double-click it, it opens a file (with the path saved in the dictionary). However, when

Solution 1:

The main issue is about creating a binding for the Treeview in the loop.

There is only one double click event that can be declared and triggered for the tree, not one by row, and here you are overriding it in each iteration.


This lambda pattern is known to declare commands for widgets inside a for/loop, and it works fine for this purpose:

lambda f=nt[x]["URIallegato"]: os.startfile(str(f))

But here you declare a default parameter f, and the lambda will be executed with an event argument given by the event binding, that's what you get in the exception : <ButtonPress event state=Mod1...

Anyway, we saw that this won't work in your case even if you fix the lambda with a second parameter to accept the event without replacing your default value f.


What i suggest is to use the values field of each row to store the information URIallegato" without displaying the column in the tree.

And then you can bind a generic event to the Treeview, by using focus() to get the selected item, and extract the value to get URI.

t=Treeview(w)
t.pack(padx=10,pady=10)

def open_item(event):
    item = t.item(t.focus())
    if item['text']:
        os.startfile(item['values'][0])

for x inlist(nt.keys()):
    value = ''if nt[x]["allegati"]:
        value = str(nt[x]["URIallegato"])
    t.insert("",x,text=nt[x]["allegati"], values=value)

t.bind("<Double-1>", open_item)

A lambda could hardly be used here if you want to check if there is an URI to open.

Solution 2:

When the event fires, tkinter will pass along an event object. You are trying to open that event object as if it were a file.

Why is that? Let's start by rewriting your lambda as a proper function. Your lambda is the equivalent of this function:

defhandle_event(f=default_value):
    os.startfile(str(default_value))

When the event fires, it does the equivalent of this:

handle_event(event)

Your script is given a single positional argument, event, which is assigned to the first keyword argument. Thus f is the same as event.

The solution is to make sure your lambda accepts the event, which it can simply ignore:

lambda event, f=nt[x]["URIallegato"]: os.startfile(str(f)))

With the above, the event object will be associated with the event parameter, and your default value for f will be passed as f.

Post a Comment for "Tkinter / Ttk - Prevent String To Buttonpress Conversion"