0

My goal is to bind a hyperlink which is from a dictionary based off the button value.

import webbrowser
from tkinter import ttk,filedialog,font
from tkinter import *

self.source_list = #list of dictionary keys
self.source_url = #dictionary of url's for the keys in source_list
#the reason I am not only using a dictionary is because the source_list is required for other functions in my project

j = 0
k = 1

    #loop to create checkbttons
    for i in range(len(self.source_list)):
        self.var = BooleanVar(value=0)
        self.source_var.append(self.var) #add var to list
        self.check_but = ttk.Checkbutton(self.window, text = self.source_list[i], var = self.source_var[i],style = "Red.TCheckbutton")
        self.check_but.bind("<Button-3>", lambda e: webbrowser.open_new(self.source_url.get(self.source_list[i]))) #dictionary of url's for each sourch
        self.check_but.grid(row=k,column=j,pady=2,columnspan=1,sticky=W)

        k += 1
        #new column
        if k == 4:
            k = 0
            j += 1

My problem is that this results in all checkbuttons getting the final assigned hyperlink.

Attempt with partial

        j = 0
        k = 1

        #loop to create checkbttons
        for i in range(len(self.source_list)):
            self.var = BooleanVar(value=0)
            self.source_var.append(self.var) #add var to list
            self.check_but = ttk.Checkbutton(self.window, text = self.source_list[i], var = self.source_var[i],style = "Red.TCheckbutton")
            self.check_but.bind("<Button-3>", partial(self.hyperlink,self.source_list[i]))
            self.check_but.grid(row=k,column=j,pady=2,columnspan=1,sticky=W)

            k += 1
            #new column
            if k == 4:
                k = 0
                j += 1

    def hyperlink(self,event,source_text):
        webbrowser.open_new(self.source_url.get(source_text))

What appears to be the source of the issue here is that the "source_text" is not being passed as the text but as an event.

SOLUTION:

All I needed to do is change the hyperlink func to use "event" i.e.


    def hyperlink(self,event,source_text):
        webbrowser.open_new(self.source_url.get(event))

Tobias Funke
  • 1,614
  • 3
  • 13
  • 23
  • There are dozens of questions on this site related to creating buttons in a loop. Have you read through them to see if they answer your question? – Bryan Oakley Jun 29 '20 at 16:39
  • @BryanOakley yes I have been stuck on this problem for 2 days and could not find any working solution here – Tobias Funke Jun 29 '20 at 16:43
  • Does this answer your question? [tkinter creating buttons in for loop passing command arguments](https://stackoverflow.com/questions/10865116/tkinter-creating-buttons-in-for-loop-passing-command-arguments) – jasonharper Jun 29 '20 at 16:43
  • @jasonharper I tried using partial and it was the same result. When the button is clicked it takes the final value from the loop instead of the preferred assigned value – Tobias Funke Jun 29 '20 at 16:45
  • 2
    Then let's see that attempt, because that (or the equivalent using a default parameter to a lambda) is definitely the way to solve this. – jasonharper Jun 29 '20 at 16:51
  • @jasonharper I tried again and am now getting a new error. It appears that the text being passed into the function is being read as an event instead of actual text. I will have to further research – Tobias Funke Jun 29 '20 at 17:15
  • 1
    Change `lambda e: ...` to `lambda e, i=i: ...`. – acw1668 Jun 29 '20 at 23:38

0 Answers0