英文:
How do I set up a slot (event handler) that takes parameters, using gtk.go.Connect()?
问题
我正在使用Go的GTK绑定。
尝试将gtk.RadioButton
的toggle
信号连接到一个函数。以下代码可以正常工作:
...
radioButton.Connect("toggled", doRadioToggle)
func doRadioToggle() {
fmt.Println("toggled")
}
...
当radioButton
被切换时,会调用doRadioToggle
函数,这很好。
但是我想连接到一个带有参数的函数,例如:
func doRadioToggle(button *gtk.RadioButton) {
fmt.Println(button.GetState())
}
gtk.go.Connect()
函数的签名如下:
func (v *Widget) Connect(s string, f interface{}, datas ...interface{})
根据我从gtkmm了解到的知识,我尝试了类似以下的代码(go绑定显然大大简化了连接的调用):
radioButton.Connect("toggled", doRadioToggle, radioButton)
在connect()
中传递的第三个参数radioButton
对应于gtk.Connect(s string, f interface{}, datas ...interface{})
中的datas
,我理解为要传递给槽函数的数据参数。
但是,使用这段代码后,doRadioToggle()
处理程序从未被调用,并且我立即出现了恐慌:
panic: reflect: Call using *glib.CallbackContext as type *gtk.RadioButton
我的问题是:如何使用gtk.go.Connect()
设置带有参数的槽函数(事件处理程序)?
英文:
I am using GTK bindings for Go.
Trying to connect a gtk.RadioButton
toggle
signal to a function. This code works fine:
...
radioButton.Connect("toggled", doRadioToggle)
func doRadioToggle() {
fmt.Println("toggled")
}
...
When radioButton is toggled, doRadioToggle is called - Good.
But I want to connect to a function that takes a parameter, for example:
func doRadioToggle(button *gtk.RadioButton) {
fmt.Println(button.GetState())
}
The gtk.go.Connect()
function has this signature:
func (v *Widget) Connect(s string, f interface{}, datas ...interface{})
Based on what I know from gtkmm, I tried code like this (the go binding has apparently greatly simplified the call to connect())
radioButton.Connect("toggled", doRadioToggle, radioButton)
The third argument passed inconnect()
- radioButton
- corresponding todatas
in
gtk.Connect(s string, f interface{}, datas ...interface{})
which I understood to mean data arguments to be passed to the slot.
But with this code, the doRadioToggle() handler never gets called, and I immediately exit with a panic:
panic: reflect: Call using *glib.CallbackContext as type *gtk.RadioButton
My question: How do I set up slot (event handler) that takes parameters using gtk.go.Connect()?
答案1
得分: 0
文档对于如何直接传递附加数据并不清楚;也许可以简单地使用闭包代替。
https://godoc.org/github.com/mattn/go-gtk/glib#CallbackContext
英文:
The documentation is not clear about how to pass additional data directly; perhaps simply use a closure instead.
https://godoc.org/github.com/mattn/go-gtk/glib#CallbackContext
答案2
得分: 0
根据来自GitHub上令人惊叹的mattn的回答:
https://github.com/mattn/go-gtk/blob/master/example/demo/demo.go#L58
采用、测试并且可用:
import(
...
"github.com/mattn/go-gtk/glib"
)
...
func ButtonHandler(ctx *glib.CallbackContext) {
fmt.Printf("按钮处理程序:%v\n", ctx.Data().(*gtk.RadioButton).GetState())
}
aRadioButton.Connect("toggled", ButtonHandler, aRadioButton)
...
在处理程序的签名中,connect()
中的datas
参数必须使用*glib.CallbackContext
传递,然后在处理程序代码中使用类型断言来获取实际的参数。
英文:
Based on response from the amazing mattn on GitHub:
https://github.com/mattn/go-gtk/blob/master/example/demo/demo.go#L58
Adopted, tested and working:
import(
...
"github.com/mattn/go-gtk/glib"
)
...
func ButtonHandler(ctx *glib.CallbackContext) {
fmt.Printf("Button Handler: %v\n", ctx.Data().(*gtk.RadioButton).GetState())
}
aRadioButton.Connect("toggled", ButtonHandler, aRadioButton)
...
Thedatas
arguments inconnect()
must be passed using*glib.CallbackContext
in the handler's signature, then, in the handler code, use type assertion to grab the actual arguments .
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论