Python Forum
[Tkinter] Search data in treeview without search button
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Search data in treeview without search button
#1
Hello,
I'm trying to make an item search engine in a treeview, if I do it with a button, it works for me.
But I want to do the search without a button, just writing in the entry I select the closest thing.
I have done this, it does not give me any errors or anything, but it does not select any similar item or anything.

self.entry_buscador = tk.Entry()
        self.entry_buscador.place(x=150, y=142, width=450, height=40)
self.entry_buscador.bind("<<KeyRelease>>", self.buscar)
def buscar(self, event):
        self.query = self.entry_buscador.get().lower()

        for item in self.treeview_almacen.get_children():
            values = self.treeview_almacen.item(item, "values")
            if self.query in values[0].lower():
                self.treeview_almacen.selection_set(item)
                self.treeview_almacen.focus(item)
                self.treeview_almacen.see(item)
            else:
                self.treeview_almacen.selection_remove(item)
what do i have wrong? what can i do
Reply
#2
If you want people to answer your questions, you should ask good questions. Your question would benefit if you provided a runnable example. If I wanted to answer the question posted here, I need to write a tkinter program with an entry and a treeview. I would have to guess how the treeview should be created and what kind of data it is populated with. Only after doing all that could I do some work towards answering the question. Why would I want to do that? Sounds like a lot of work that should be done by the person asking for help.

But, to answer your question.

PROBLEM 1:
Your code with the button didn't work either, unless it was very different than the posted code. Your tree search only finds complete matches, not the "closest thing". If you want to do a partial match, you might want to use str.startswith(). This will find table entries that start with the same letters as in the entry.

https://python-reference.readthedocs.io/...swith.html

If you want to search for a partial match anywhere in the string you should look at using "in" (if substring in string). in will find strings that contain the string in entry. Neither of these do anything to find the "closest match". If it is important to do that, you should look at difflib.

https://docs.python.org/3/library/difflib.html

PROBLEM 2:
The posted code would match a complete entry, but the bind() is messed up. "<<KeyRelease>>" is not a valid event. I think you mean "<KeyRelease>".

When trying something new, I write little experiment programs. It lets me focus on few things and not have to worry about integrating the new feature into my program. These little programs are also quite useful when asking questions on the forum. If I was testing out this keybinding thing I would write a program like this:
import tkinter as tk

root = tk.Tk()
entry = tk.Entry(root, width=30)
entry.bind("<<KeyRelease>>", lambda event: print(entry.get()))
entry.pack()
root.mainloop()
Running the program I would see there is nothing getting printed when I type in the entry box. Now I know the problem is with getting events from the entry. This is a much smaller problem than I had before. If you had done this I bet it would've led you to research what events you can bind, and you would've noticed the KeyRelease event is surounded by <>, not <<>>.

PROBLEM 3:
I think binding KeyRelease is the wrong approach. Sure it will work for typing, but what about cut and paste? Instead of binding the keyboard, you should create a StringVariable and trace() changes to the string variable. This will report any change to the text in the entry, and that is what you really want.
import tkinter as tk

root = tk.Tk()
var = tk.StringVar()
entry = tk.Entry(root, textvariable=var, width=30)
var.trace("w", callback=lambda a, b, c: print(var.get()))
entry.pack()
root.mainloop()
Here's an example that prints the word that best matches the entry (according to difflab.SequenceMatcher).
import tkinter as tk
import re
from difflib import SequenceMatcher


def match(text):
    text = text.lower()
    matches = [(SequenceMatcher(None, text, word).ratio(), word) for word in words]
    print(max(matches)[1])


with open(__file__, "r") as file:
    words = {word.lower() for word in re.split("\W+", file.read())}

root = tk.Tk()
var = tk.StringVar()
tk.Entry(root, textvariable=var, width=30).pack()
var.trace("w", callback=lambda a, b, c: match(var.get()))
root.mainloop()
You should play with startswith(), "in" and difflib to see which you like the most.
TomasSanchexx likes this post
Reply
#3
(Aug-11-2023, 12:38 PM)TomasSanchexx Wrote: Hello,
I'm trying to make an item search engine in a treeview, if I do it with a button, it works for me.
But I want to do the search without a button, just writing in the entry I select the closest thing.
I have done this, it does not give me any errors or anything, but it does not select any similar item or anything.

self.entry_buscador = tk.Entry()
        self.entry_buscador.place(x=150, y=142, width=450, height=40)
self.entry_buscador.bind("<<KeyRelease>>", self.buscar)
def buscar(self, event):
        self.query = self.entry_buscador.get().lower()

        for item in self.treeview_almacen.get_children():
            values = self.treeview_almacen.item(item, "values")
            if self.query in values[0].lower():
                self.treeview_almacen.selection_set(item)
                self.treeview_almacen.focus(item)
                self.treeview_almacen.see(item)
            else:
                self.treeview_almacen.selection_remove(item)
what do i have wrong? what can i do


Thank you very much, yes it works correctly.

solution:
self.entry_finder.bind("<KeyRelease>", self.find)
Reply
#4
I really think using KeyRelease is a mistake.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] How to insert data json to treeview tkinter? Shakanrose 8 4,485 Jan-19-2023, 03:58 PM
Last Post: Shakanrose
  [Tkinter] Trying to add data into a shelf from a submit button TWB 8 1,877 Jan-06-2023, 11:30 PM
Last Post: TWB
  search is not finding documentation i want Skaperen 1 901 Aug-26-2022, 08:17 AM
Last Post: Gribouillis
  [PyQt] [Solved]Display Search Results in QTable Extra 5 2,477 Jun-29-2022, 10:20 PM
Last Post: Extra
  Can't get tkinter button to change color based on changes in data dford 4 3,450 Feb-13-2022, 01:57 PM
Last Post: dford
  [Tkinter] [split] Is there a way to embed a treeview as a row inside another treeview? CyKlop 5 3,408 Oct-20-2021, 12:14 AM
Last Post: CyKlop
  [Tkinter] Text.search() regexp not working rfresh737 11 5,036 Apr-16-2021, 06:56 PM
Last Post: rfresh737
  Button to add data to database and listbox SalsaBeanDip 1 2,887 Dec-06-2020, 10:13 PM
Last Post: Larz60+
  [Tkinter] acceleration of data output in treeview tkinter Vladimir1984 4 4,239 Nov-21-2020, 03:43 PM
Last Post: Vladimir1984
  Listbox search code partially works chesschaser 9 3,950 May-05-2020, 01:08 PM
Last Post: chesschaser

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020