Adding button.onClick proc in loop return only last button
nobodybusiness opened this issue · 1 comments
nobodybusiness commented
Minimal code to recreate situation:
app.init()
var window = newWindow()
var container = newLayoutContainer(Layout_Vertical)
var allButtons : seq[Button]
for i in 1..10:
allButtons.add(newButton($i))
for button in allButtons:
container.add(button)
button.onClick=proc(event:ClickEvent)=
window.alert(button.text)
window.add(container)
window.show()
app.run()
When any button is clicked, values return is for last added button.
In above example window.alert always show 10.
It is possible to work with in loop onClick events?
simonkrauter commented
The reason for this is how Nim captures loop variables in closures. See https://nim-lang.org/docs/manual.html#closures-creating-closures-in-loops
Solution 1: Don't use loop variable in closure
import NiGui
app.init()
var window = newWindow()
var container = newLayoutContainer(Layout_Vertical)
var allButtons: seq[Button]
for i in 1..10:
allButtons.add(newButton($i))
for button in allButtons:
container.add(button)
button.onClick = proc(event: ClickEvent) =
window.alert(cast[Button](event.control).text)
window.add(container)
window.show()
app.run()
Solution 2: Capture loop variable explicitly:
import NiGui
import std/sugar
app.init()
var window = newWindow()
var container = newLayoutContainer(Layout_Vertical)
var allButtons: seq[Button]
for i in 1..10:
allButtons.add(newButton($i))
for button in allButtons:
capture button:
container.add(button)
button.onClick = proc(event: ClickEvent) =
window.alert(button.text)
window.add(container)
window.show()
app.run()