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 you double-click a row you'll get this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Maicol\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py",
line 1699, in __call__
return self.func(*args)
File "C:\Users\Maicol\Documents\Projects\App_WINDOWS\School_Life_Diary\note.py",
line 195, in <lambda>
lambda f=nt[x]["URIallegato"]: os.startfile(str(f)))
FileNotFoundError: [WinError 2] Can't find the specified file: '<ButtonPress event state=Mod1 num=1 x=677 y=37>'
The problem is this code:
t.bind("<Double-1>", lambda f=nt[x]["URIallegato"]: os.startfile(str(f)))
that allows the double-clicking and opening of the file.
Here is the full Treeview
code:
t=Treeview(w)
t.pack(padx=10,pady=10)
for x in list(nt.keys()):
t.insert("",x,text=nt[x]["allegati"])
if nt[x]["allegati"]!="":
t.bind("<Double-1>",
lambda f=nt[x]["URIallegato"]: os.startfile(str(f)))
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:
def handle_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
.