curselection on treeview tkinter - python

I'm trying to extract the data of what row is selected on a treeview in tk.
So far I've tried the following:
def select_item(event):
global selected_item
index = data.curselection()[0]
selected_items = data.get(index)
print(selected_items)
#configure scrollbar
my_tree.bind('<<TreeviewSelect>>', select_item)
I was following a tutorial of some guy doing it, and my data layout is the exact same as his, as can be seen:
data = [('0','John', 'Smith','1','2','3'),('1','Ayoung', 'Smith','2','3','6'),('2','Enshean', 'Smith','6','1','4'),
('3','Emma', 'Smieth','1','4','5'),('4','Isabel', 'Smith','6','1','4')]
When I try my running my code and selecting an item on the treeview I get the following error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/Users/johnminton/Documents/Python/Python database internal/deletestudent.py", line 35, in select_item
index = data.curselection()[0]
AttributeError: 'list' object has no attribute 'curselection'

I used the following, and it does its job.
def select_item(event):
rowid=my_tree.identify_row(event.y)
item=my_tree.item(my_tree.focus())
print(item['values'])
my_tree.bind('<ButtonRelease-1>', select_item)

The error is telling you that data is a list, not a treeview widget. You must call curselection() on a treeview object. Well, except for the case that even the Treeview widget doesn't have that method. To get the currently selected items in Treeview you use selection., In your case it should be one of the following:
event.widget.selection()
... or the following, assuming that my_tree is a global variable:
my_tree.selection()

Related

curselection() missing 1 required positional argument: 'self'

lbox = Listbox
def Show():
Selected=lbox.get(lbox.curselection())
with open("pass.json","r+") as jfile:
try:
data=json.load(jfile)
for i in data['Details']:
if Selected==i["Site"]:
password_text.set(i["Password"])
uname_text.set(i["Username"])
except JSONDecodeError:
pass
I wanted to use curselection() but curselection() missing 1 required positional argument: 'self' is coming all the time
lbox was declared in another function which is given below
def Show_fun():
newWindow=Toplevel(window)
newWindow.title("Show your stuff")
newWindow.geometry("600x400")
Label(newWindow,text="Show passwords").grid(row=0,column=1,pady=10)
Label(newWindow,text="Site name : ").grid(row=1,pady=10)
lbox=Listbox(newWindow)
lbox.grid(row=1,column=2)
sites=[]
with open("pass.json","r+") as jfile:
try:
data=json.load(jfile)
for i in data['Details']:
sites.append(i["Site"])
except JSONDecodeError:
pass
lbox.config(height=lbox.size())
for i in sites:
lbox.insert(lbox.size(),i)
#site_entry = Entry(newWindow,textvariable = site_text,width=20,state=DISABLED).grid(row=1,column=2)
Label(newWindow,text="Username : ").grid(row=2,pady=10)
uname_entry=Entry(newWindow,textvariable=uname_text,state=DISABLED).grid(row=2,column=2)
Label(newWindow,text="Password : ").grid(row=3,pady=10)
pasword_entry=Entry(newWindow,textvariable=password_text,width=20,state=DISABLED).grid(row=3,column=2)
Button(newWindow,text="Show",command=Show,fg="#00FF00",bg="black",pady=10).grid(row=4,column=1)
I saw many YT vids . ListBox was working globally but in my its not working globally
EDIT: after giving parenthesis to ListBox() New error arises
Traceback (most recent call last):
File "C:\Program Files\Python38\lib\tkinter\__init__.py", line 1895, in __call__
return self.func(*args)
File "d:/Python files/cybersecurity/password manager/password_test.py", line 24, in Show
Selected=lbox.get(lbox.curselection())
File "C:\Program Files\Python38\l`enter code here`ib\tkinter\__init__.py", line 3190, in get
return self.tk.call(self._w, 'get', first)
_tkinter.TclError: bad listbox index "": must be active, anchor, end, #x,y, or a number
The error message simply means that the method was not invoked on the object but on the class instead. In the first code snippet, you didn't seem to instantiate a ListBox object.
You must change the line
lbox = Listbox
to something like:
# Tkinter window object
window = Tk()
# Create ListBox object and bind to the Tkinter window
lbox = Listbox(window)
In the above snippet, an instance of ListBox is created on which the method curselection() could be called. Give more emphasis to the argument passed to ListBox. The window variable used above is an instance of the Tk class which essentially constructs the Tkinter window. Without this argument, the listbox widget won't know which window it must bind to.

Calling an object method using a function

I am playing around tkinter, and I was wondering if I had declared a method within an object, can I call it using the 'protocol' method of tkinter? or any function to be exact ie.
class Notepad():
...
...
def exit_func():
#Messagebox command warning 'You are exiting'
root = tk.Tk()
notepad = Notepad(root)
root.geometry("800x500")
root.mainloop()
#Problem is here
root.protocol("WM_DELETE_WINDOW", app.exit_func())
I tried this with my program, where my 'exit_func' had a 'get' function from tkinter and i got this error:
Traceback (most recent call last):
File "Notepad_with_console.py", line 204, in <module>
root.protocol("WM_DELETE_WINDOW", notepad.exit_file())
File "Notepad_with_console.py", line 175, in exit_file
if self.text.get(1.0,tk.END) != '' and self.current_file_dir == '':
File "C:\Anaconda\lib\tkinter\__init__.py", line 3246, in get
return self.tk.call(self._w, 'get', index1, index2)
_tkinter.TclError: invalid command name ".!text"
Is there a reason for this? Thanks!
root.protocol requires a reference to a function. Instead, you're immediately calling a function and then passing in the result.
Consider this code:
root.protocol("WM_DELETE_WINDOW", app.exit_func())
That code is functionally identical to this:
result = app.exit_func()
root.protocol("WM_DELETE_WINDOW", result)
Instead, you need to pass in a reference to the function:
root.protocol("WM_DELETE_WINDOW", app.exit_func)

root.after unable to find function_name

I am trying to put together a GUI that would read from a continuously updated TXT file and updated every once in a while. So far I succeeded with the first part and I am failing to use 'root.after()' to loop the whole thing but it results in NameError:
import tkinter as tk
root = tk.Tk()
class App:
def __init__(self, root):
frame = tk.Frame(root)
frame.pack()
iAutoInEN = 0
iAvailableEN = 0
self.tkAutoInEN = tk.StringVar()
self.tkAutoInEN.set(iAutoInEN)
self.tbAutoInEN = tk.Label(root, textvariable=self.tkAutoInEN)
self.tbAutoInEN.pack(side=tk.LEFT)
self.button = tk.Button(frame, text="Start", fg="red",
command=self.get_text)
self.button.pack(side=tk.LEFT)
def get_text(self):
fText = open("report.txt") #open a text file in the same folder
sContents = fText.read() #read the contents
fText.close()
# omitted working code that parses the text to lines and lines
# to items and marks them with numbers based on which they are
# allocated to a variable
if iLineCounter == 1 and iItemCounter == 3:
iAutoInEN = int(sItem)
self.tkAutoInEN.set(iAutoInEN)
root.after(1000,root,get_text(self))
app = App(root)
root.mainloop()
try:
root.destroy() # optional; see description below
except:
pass
The first instance runs without any problems and updates the value from 0 to the number in the TXT file but is accompanied with an error
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\...\Python35\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:/.../pythonlab/GUI3.py", line 117, in get_text
self.after(1000,root,get_text())
NameError: name 'get_text' is not defined
EDIT:
When changed to the recommended "self.after(1000,self.get_text)"
class App:
...
def get_text(self):
fText = open("report.txt") #open a text file in the same folder
sContents = fText.read() #read the contents
fText.close()
# omitted code
if iLineCounter == 1 and iItemCounter == 3:
iAutoInEN = int(sItem)
self.tkAutoInEN.set(iAutoInEN)
self.after(1000,self.get_text)
Error changes
Traceback (most recent call last):
File "C:/.../pythonlab/GUI3.py", line 6, in <module>
class App:
File "C:/.../pythonlab/GUI3.py", line 117, in App
self.after(1000, self.get_text)
NameError: name 'self' is not defined
Also please consider this is my very first programme (not only) in Python, so I would appreciate if you are a little bit more explicit with your answers (e.g. when pointing out an indentation error, please refer to an exact line of code).
Because get_text is a method of App class you should call it as self.get_text.
After is a tkinter method. In that case you should call it as root.after. And self refers to the class you are in. So because get_text is a method of current class you should call is with self which is like this in other programming languages like Java.
...
root.after(1000, self.get_text)
...
Firstly, like James commented, you should fix your indentation so that the functions are a part of the class.
Then, change this line
root.after(1000,root,get_text(self))
to this
root.after(1000, self.get_text)
Check out the answer to the following question, which uses the code I just gave you:
Tkinter, executing functions over time

tkinter traceback error on python 3.5.1 windows 8.1 [duplicate]

This question already has answers here:
Tkinter: AttributeError: NoneType object has no attribute <attribute name>
(4 answers)
Closed 6 years ago.
I want to get an input data from user and put it into text file, but there's an error as follows:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\dasom\AppData\Local\Programs\Python\Python35-32\Lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:/Users/dasom/PycharmProjects/Exercise/4.pyw", line 5, in save_data
filed.write("Depot:\n%s\n" % depot.get())
AttributeError: 'NoneType' object has no attribute 'get'`
It says about line 1549 in init.py file, I looked up for it and I coudn't understand what the problem is.
def __call__(self, *args):
"""Apply first function SUBST to arguments, than FUNC."""
try:
if self.subst:
args = self.subst(*args)
return self.func(*args)
except SystemExit:
raise
except:
self.widget._report_exception()
Here's my whole code
from tkinter import *
def save_data():
filed = open("deliveries.txt", "a")
filed.write("Depot:\n%s\n" % depot.get())
filed.write("Description :\n%s\n" % description.get())
filed.write("Address :\n%s\n" % address.get("1.0", END))
depot.delete(0, END)
description.delete(0, END)
address.delete("1.0", END)
app = Tk()
app.title('Head-Ex Deliveries')
Label(app, text='Depot:').pack()
depot = Entry(app).pack()
Label(app, text="Description:").pack()
description = Entry(app).pack()
Label(app, text='Address:').pack()
address = Text(app).pack()
Button(app, text='save', command=save_data).pack()
app.mainloop()
Actually, I just typed the code of textbook. Your help will be greatly appreciated. Thanks.
If the textbook has code like that, it's a poor textbook. This line:
depot = Entry(app).pack()
is doing two things. First it creates an Entry, and then it places it into the app. Unfortunately, the pack() method acts in-place and returns None instead of a reference to the original Entry widget. Split it up:
depot = Entry(app)
depot.pack()
Do this for all similar instances of assigning the None return value from an in-place method to a reference that you expect to point to a useful object.

Python : AttributeError

I get an AttributeError I can't seem to work out.
I'm working with two classes.
The first class goes something like that.
class Partie:
def __init__(self):
# deleted lines
self.interface = Interface(jeu=self)
def evaluerProposition(self):
# computations
self.interface.afficherReponse()
Introducing second class (in a separate file).
class Interface:
def __init__(self, jeu):
self.jeu = jeu
self.root = tkinter.Tk()
# stuff
def onClick(self, event):
# talk
self.jeu.evaluerProposition()
def afficherReponse(self):
# stuff
I start the whole thing by
partie = Partie()
All manipulations on my widget work fine until some click event causes
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
return self.func(*args)
File "C:\Users\Canard\Documents\My Dropbox\Python\AtelierPython\Mastermind\classeInterface.py", line 197, in clic
self.jeu.evaluerProposition()
File "C:\Users\Canard\Documents\My Dropbox\Python\AtelierPython\Mastermind\classeJeu.py", line 55, in evaluerProposition
self.interface.afficherReponse()
AttributeError: 'Partie' object has no attribute 'interface'
I typed in the interpretor
>>> dir(partie)
and got a long list in return with 'interface' among the attributes.
Also typed
>>> partie.interface
<classeInterface.Interface object at 0x02C39E50>
so the attribute seems to exist.
Following the advice in some former post, I checked the instance names do not coincide with module names.
I am confused.
Most likely, in some code that you're not showing us, you're doing something like this:
self.some_button = tkinter.Button(..., command=self.interface.onClick())
Note the trailing () on onClick(). This would cause the onClick method to be called at the time the button is created, which is probably before your constructor is done constructing the instance of the Partie class.

Categories