Home > Enterprise >  How to set a particular element of a list to be displayed when hover over on a particular button, wh
How to set a particular element of a list to be displayed when hover over on a particular button, wh

Time:10-10

I know this is going to be simple but I'm not getting it, anyone please help me out of this problem. This is like, when I hover over button0 it should set the first element of a list (element at the 0th index) on a label. When I hover over button4 then it should set the fourth element of the list (element of the 3rd index) on the label.

import tkinter as tk


root = tk.Tk()
root.geometry("200x200")

words = [
            'Standard Converter',
            'Scientific Converter',
            'Currency Converter',
            'Binary ⇌ Decimal Converter'
        ]
            # for i in range(0, 4):

frame = tk.Frame(root)
frame.pack()

b = {}
for i in range(0, 4):
    word = words[i]
    def button_leave(e):
        statusvar.set("Main Page")
    def button_enter(e):
        statusvar.set(word)
    b[i] = tk.Button(frame, text = i, width =10)
    b[i].pack(pady = 10)
    b[i].bind("<Enter>", button_enter)
    b[i].bind("<Leave>", button_leave)



statusvar = tk.StringVar()
statusvar.set("Main Page")
subvar = tk.Label(frame,bg = 'red', textvariable=statusvar)
subvar.pack()
root.mainloop()

CodePudding user response:

The problem is that all the iterations of the loop are executed before you'll press any button, and you told the button_enter function to set the statusvar variable to words[i], but after all the iterations are done, i is gonna be 3, so all the buttons are gonna set the text to words[3].

One solution could be to set the index as a custom attribute to the buttons, and then use that as an index:

import tkinter as tk


root = tk.Tk()
root.geometry("200x300")

words = [
            'Standard Converter',
            'Scientific Converter',
            'Currency Converter',
            'Binary ⇌ Decimal Converter'
        ]

frame = tk.Frame(root)
frame.pack()

b = {}
for i in range(4):
    word = words[i]

    b[i] = tk.Button(frame, text=i, width=10)
    b[i].pack(pady = 10)

    # custom attribute called index 
    #to save the index of the text this button should display
    b[i].index = i

    def button_leave(e):
        statusvar.set("Main Page")
    def button_enter(e):
        # retrive the custom attribute of the hovered element
        statusvar.set(words[e.widget.index])
    b[i].bind("<Enter>", button_enter)
    b[i].bind("<Leave>", button_leave)

statusvar = tk.StringVar()
statusvar.set("Main Page")
subvar = tk.Label(frame,bg = 'red', textvariable=statusvar)
subvar.pack()
root.mainloop()

P.S I made the window slightly bigger so the label is visible and added the tkinter import, please do these things yourself next time

P.P.S. I see you're a beginner, I know this is not part of the answer but I would strongly suggest to learn only Python without tk first, and then move to tk, also try to use Google as much as you can and post here only if you really can't find a solution

CodePudding user response:

You are recreating the same function button_enter every time in the loop. So when the loop ends, the last iteration of the loop which is 3 will be used to create the last word which is 'Binary ⇌ Decimal Converter'. However, you simply used the same function for all of your buttons so you recreated the function 4 times but only the last time it created the function will happen. I know it is a little bit confusing so please ask me questions if you have doubts.

So what I came up with is that instead changing the function itself, we can just use the variable word as a parameter to the function button_enter. The function is the same, but you just pass different information from these 4 buttons. Here is the code you asked for:

import tkinter as tk

root = tk.Tk()
root.geometry("200x200")

words = [
            'Standard Converter',
            'Scientific Converter',
            'Currency Converter',
            'Binary ⇌ Decimal Converter'
        ]
            # for i in range(0, 4):

frame = tk.Frame(root)
frame.pack()

b = {}

def button_leave(e):
        statusvar.set("Main Page")
def button_enter(e, w):
    statusvar.set(w)

for i in range(4):
    word = words[i]
    b[i] = tk.Button(frame, text = i, width =10)
    b[i].pack(pady = 10)
# Use lambda for the parameters
    b[i].bind("<Enter>", lambda e, w = word: button_enter(e, w))
    b[i].bind("<Leave>", button_leave)

statusvar = tk.StringVar()
statusvar.set("Main Page")
subvar = tk.Label(frame,bg = 'red', textvariable=statusvar)
subvar.pack()
root.mainloop()

Let me know if this does not work for you.

  • Related