Edm1795 / LibraryCat

This is a library catalogue search and display program. The program offers a much better organization of results than that given by the industry standard. Books, DVDs, Blurays, and CDs are all separated into clean and simple columns giving only relevant information. The Search History function is one particularly effective tool helping users return to previous searches. This display concept is better suited in particular to librarians themselves who need to search for items for customers. It gives consistent and immediately readable results
0 stars 0 forks source link

Create a Button Which Contains a List of All Previous Searches #2

Open Edm1795 opened 2 years ago

Edm1795 commented 2 years ago

Cache all results into a list of lists which the button can access. Each list will be referenced by the search term used for it. Clicking on any item will load up those results directly into the interface, by passing a rerun of searching the catalogue.

Edm1795 commented 2 years ago

This script creates a dropdown menu which populates by a list using the "" command in front of the list -- drop= OptionMenu(win, menu, list1)

Import the required libraries

from tkinter import *

Create an instance of tkinter frame

win = Tk()

Define the size of window or frame

win.geometry("715x250")

Set the Menu initially

menu = StringVar() menu.set("Select Any Language")

list1 = ["C++", "Java","Python","JavaScript","Rust","GoLang"]

Create a dropdown Menu

drop= OptionMenu(win, menu, *list1) drop.pack()

win.mainloop()

Edm1795 commented 2 years ago

Proper Solution

Use a Menu (rather than an OptionMenu), use add_command and use lamda in the function call. Without lamda the function call will be called instantly on creation of the command. But also store the variable needed (searchTerm) into a new variable directly inside of the lambda function:

def displaySelected(searchTerm):
            # Gets item clicked on in menu then updates the screen to those corresponding results

            print('function call initiated by clicking:', searchTerm)
            indexOfSearchTerm = self.searchTermsCache.index(searchTerm)
            self.clearTextFields()
            self.updateResults(self.resultsCache[indexOfSearchTerm])
            # print('Search term sent from Menu History:')
            # print(self.searchTermsCache.index(searchTerm))

        self.history1.delete(0, "end")  # clear history list before reposting new terms, otherwise duplicates show

for searchTerm in self.searchTermsCache:  # Populate Search History list from cache
            self.history1.add_command(label=searchTerm, command=lambda x=searchTerm: displaySelected(x))

Note the command=lambda x=searchTerm: displaySelected(x)) contains x = searchTerm, then the function call takes x so that the proper searchTerm is saved into each instance of the search history.

Edm1795 commented 2 years ago

Option Menu

Search History Menu

    def displaySelected(choice):
        # Gets item clicked on in menu then updates the screen to those corresponding results
        choice = variable.get()
        indexOfSearchTerm = self.searchTermsCache.index(choice)
        self.clearTextFields()
        self.updateResults(self.resultsCache[indexOfSearchTerm])
        print(choice)
        print(self.searchTermsCache.index(choice))

    # setting variable for Integers

    self.master.option_add('*tearOff', FALSE)
    variable = StringVar()
    variable.set('         ')
    self.searchTermsCache = [1,2,3,4]
    # creating widget
    self.dropdown = OptionMenu(
        self.master,
        variable,
        *self.searchTermsCache,
        command=displaySelected
    )
    self.dropdown.grid(row=0, column=2)
    #for item in self.searchTermsCache:  # populate drop down menu with items stored in searchTermsCache
     #   dropDownMenu.add_command(label=item, command=get)
Edm1795 commented 2 years ago

Code Example of lambda with stored variable inside the lambda function:

import tkinter as tk

def f(x):
    print(x)

root = tk.Tk()
menubar = tk.Menu(root)
root.configure(menu=menubar)
menu = tk.Menu(menubar, tearoff=False)
l = ['one', 'two', 'three']
for i in l:
    menu.add_command(label=i, command=lambda x=i: f(x))
menubar.add_cascade(label='File', menu=menu)
root.mainloop()

Another Method for Solving the Scope Problem:

What you need to do is introduce a new level of scope, with a new binding, for each of the items. The easiest way to do that is to wrap it in a new function definition:

for item in items:
    def item_command(name):
        def new_command():
            print(name)
        return new_command

    map[item] = item_command(item)