-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Project question] Getting a string parameter in SimpleAction signal handler? #741
Comments
Hi, package main
import (
"fmt"
"log"
"os"
"unsafe"
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
)
func onActivate(app *gtk.Application) {
win, err := gtk.ApplicationWindowNew(app)
if err != nil {
log.Fatal(err)
}
win.SetDefaultSize(320, 240)
box, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 2)
if err != nil {
log.Fatal(err)
}
B1, err := gtk.ButtonNewWithLabel("B1")
if err != nil {
log.Printf("Got error: %v\n", err)
return
}
B2, err := gtk.ButtonNewWithLabel("B2")
if err != nil {
log.Printf("Got error: %v\n", err)
return
}
B3, err := gtk.ButtonNewWithLabel("B3")
if err != nil {
log.Printf("Got error: %v\n", err)
return
}
uB1 := "from B1"
uB2 := "from B2"
uB3 := "from B3"
// Signals
B1.Connect("clicked", func(mb *gtk.Button, data unsafe.Pointer) {
unifiedPrint(data)
}, unsafe.Pointer(&uB1))
B2.Connect("clicked", func(mb *gtk.Button, data unsafe.Pointer) {
unifiedPrint(data)
}, unsafe.Pointer(&uB2))
B3.Connect("clicked", func(mb *gtk.Button, data unsafe.Pointer) {
unifiedPrint(data)
}, unsafe.Pointer(&uB3))
// Packing
box.Add(B1)
box.Add(B2)
box.Add(B3)
win.Add(box)
win.ShowAll()
}
// Single action handled by multiple buttons
func unifiedPrint(from unsafe.Pointer) {
switch *(*string)(unsafe.Pointer(from)) {
case "from B1":
fmt.Println("B1 clicked")
case "from B2":
fmt.Println("B2 clicked")
case "from B3":
fmt.Println("B3 clicked")
}
}
func main() {
app, err := gtk.ApplicationNew("org.microtest.StackBugs", glib.APPLICATION_FLAGS_NONE)
if err != nil {
log.Fatal(err)
}
app.Connect("activate", onActivate)
os.Exit(app.Run(os.Args))
} I Use unsafe.Pointer to pass arguments, that permit to use any type, you can replace by string type. ...
B1.Connect("clicked", func(mb *gtk.Button, data string) {
unifiedPrint(data)
}, uB1)
B2.Connect("clicked", func(mb *gtk.Button, data string) {
unifiedPrint(data)
}, uB2)
B3.Connect("clicked", func(mb *gtk.Button, data string) {
unifiedPrint(data)
}, uB3)
...
// Single action handled by multiple buttons
func unifiedPrint(from string) {
switch from {
case "from B1":
fmt.Println("B1 clicked")
case "from B2":
fmt.Println("B2 clicked")
case "from B3":
fmt.Println("B3 clicked")
}
} You can use gtk.Button.SetName("xx") to obtain the same result, by acting as object tag to distingate them (SetName is usually used for CSS objects naming) . However, if you can give me a minimal example of your usage for GValue that return Hope this help. |
Thanks, I got your point. The thing here is you're not using Actions (like And when a handler is invoked by an action, the caller (the first argument to the handler) is the action, not the button. In order to address that, GTK dudes have invented action targets, then the so-called detailed action on the button looks like Using different targets on different widgets you can easily distinguish between them even when they refer to the same action. The target value is then supposed to become the second argument to the handler — but gotk3 fails to handle that yet. For now, I've worked around that by using the |
Here's a minimal example that reproduces the problem: package main
import (
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
"log"
"os"
)
func onActivate(app *gtk.Application) {
win, err := gtk.ApplicationWindowNew(app)
if err != nil {
log.Fatal(err)
}
win.SetDefaultSize(320, 240)
box, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 2)
if err != nil {
log.Fatal(err)
}
// Add action
a := glib.SimpleActionNew("whatever", glib.VARIANT_TYPE_STRING)
_, _ = a.Connect("activate", func(a *glib.Object, val string) {})
app.AddAction(a)
// Add a button
b, err := gtk.ButtonNewWithLabel("Button")
if err != nil {
log.Fatal(err)
}
b.SetDetailedActionName("app.whatever('I am clicked!')")
// Packing
box.Add(b)
win.Add(box)
win.ShowAll()
}
func main() {
app, err := gtk.ApplicationNew("com.yktoo.test-actions", glib.APPLICATION_FLAGS_NONE)
if err != nil {
log.Fatal(err)
}
_, _ = app.Connect("activate", onActivate)
os.Exit(app.Run(os.Args))
} Once you click the button, you get two errors:
The first one makes it already tough, as a The second one is a total showstopper, apparently it comes from here. |
In response to gotk3#741 Register GValue marshalers for: GSimpleAction, GAction, GPropertyAction Add marshaller for GVariant (WIP) Add: g_action_print_detailed_name() g_variant_parse()
In response to gotk3#741 [WIP] Register GValue marshalers for: GSimpleAction, GAction, GPropertyAction Add marshaller for GVariant (WIP) Add: g_action_print_detailed_name() g_variant_parse()
available in: #743 Now i'm facing to another issue: |
I think it's okay now, your example (with some little modifications) should work as expected, tell me if it's ok or not for you, you can retrieve full branch from my repository under its name for testing purpose while waiting PR merging. package main
import (
"fmt"
"log"
"os"
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
)
func onActivate(app *gtk.Application) {
win, err := gtk.ApplicationWindowNew(app)
if err != nil {
log.Fatal(err)
}
win.SetDefaultSize(320, 240)
box, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 2)
if err != nil {
log.Fatal(err)
}
// Add action
a := glib.SimpleActionNew("whatever", glib.VARIANT_TYPE_STRING)
_, _ = a.Connect("activate", func(sAction *glib.SimpleAction, val string) {
fmt.Println("hey!", sAction.GetName(), val)
})
app.AddAction(a)
// Add a button
b, err := gtk.ButtonNewWithLabel("Button")
if err != nil {
log.Fatal(err)
}
// Same as your implementation but it's for test
objVal := glib.VariantFromString("I am clicked!")
vd := glib.ActionPrintDetailedName("app.whatever", objVal)
b.SetDetailedActionName(vd)
// Packing
box.Add(b)
win.Add(box)
win.ShowAll()
}
func main() {
app, err := gtk.ApplicationNew("com.yktoo.test-actions", glib.APPLICATION_FLAGS_NONE)
if err != nil {
log.Fatal(err)
}
_, _ = app.Connect("activate", onActivate)
os.Exit(app.Run(os.Args))
} |
Solving #741- Add possibility to use GVariant in signal handler
I see there this method for
IActionable
:SetDetailedActionName(name string)
, which can be used in combination withglib.SimpleActionNew(..., glib.VARIANT_TYPE_STRING)
to get a parameter in theactivate
signal handler of the action.This, however, doesn't seem to be supported:
My issue is I have a single action and multiple items bound to it so I need to be able to figure out which has triggered the action.
Is it at all possible to pass something from an actionable widget into the handler?
The text was updated successfully, but these errors were encountered: