1

Basically, I am trying to parse the information from a list into lines in a text widget where each line has a hyperlink related to a field from the list. I am using effbot's HyperlinkManager to attempt to accomplish this. What I currently have is this:

link = hyperlink.link(panel)
if table == '1':
      panel.insert(END,' [Part Number]              [Part Name]\n')
      for row in (queries.partQuery(table,partResult.get())):
         number = row[1]
         name = row[2]
         panel.insert(END,'*[')
         panel.insert(END,number, link.add(lambda: test(number)))
         panel.insert(END,']')
         panel.insert(END,' ' * (25-len(number)))
         panel.insert(END,name)
         panel.insert(END,'\n')
      panel.config(state='disabled')

def test(x):
   print (x)

partQuery returns rows from a MySQL db which match certain search criteria, and then I am attempting to insert each result as a line in the text widget 'panel', however, I want the first field in the line (number) to be a hyperlink which I can then click to call a function (test, in this example), and perform an action using 'number' as a variable.

What is occurring however, is that the last result returned is being save as 'number', so whenever I click on one of the links generated in a search, regardless of the line, the last result is printed.

Thanks in advance to anyone who takes time to help me with this conundrum.

EDIT: After following the link in Abarnert's comment, I was able to resolve this issue simply by changing lambda: test(number) to lambda number=number: test(number).

  • I'm confused by something. What does `hyperlink.link(panel)` return? There's no `link` method listed on the doc page you linked to, and I can't see what you'd need it for. However, I'm 90% sure this isn't related to your problem. – abarnert Oct 23 '14 at 00:29
  • The problem is that you're creating a bunch of different closures, all referring to the same `number` variable. So, as `number` changes, all those closures are going to see the same `number` variable. This is explained in the Python FAQ; the usual workaround is to explicitly pass in the value (e.g., by binding it as a default argument). – abarnert Oct 23 '14 at 00:31
  • See [Why do lambdas defined in a loop with different values all return the same result](https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result) from the FAQ. Meanwhile, I'm almost positive this is a dup of other questions here, so let me find a good one that explains things nicely for you, and close this question as a dup so you can use that answer. – abarnert Oct 23 '14 at 00:32
  • The dup I found seems to be the closest thing to a canonical SO answer to this question, although it's a bit more in-depth and technical than you probably want. If you're still confused after reading that and the FAQ entry, you can explore the linked and related questions on the right of that one, or maybe write a new question asking to explain something. – abarnert Oct 23 '14 at 00:34
  • @abarnert, thank you! That is exactly what I am running into. As for the 'link' method, I forgot to mention that I renamed the class from HyperlinkManager to link in my module. Thanks again. – Zack Krasowski Oct 23 '14 at 00:38
  • Being new to this place, I'm not hip on all the etiquette; should I delete my post, or leave it as a forward to the correct answer? – Zack Krasowski Oct 23 '14 at 00:39
  • I don't think you should delete it. The question comes up on meta all the time; the consensus seems to be that dups are a good thing if (a) they're well-written and well-formed questions, and (b) they're different enough from the canonical question, because that means more ways for people to find the answer they need by (site or google) search. And I think yours qualifies as both (a) and (b), but obviously that's a judgment call. – abarnert Oct 23 '14 at 01:09

0 Answers0