Go non ha una UI di default. Si possono utilizzare dei bindings con GTK3 o delle UI native
go mod init luca.innocenti.gtk3test
si caricano i moduli
go get github.com/gotk3/gotk3/glib
go get github.com/gotk3/gotk3/gtk
si apre quindi Glade per creare la pgina (una semplice textbox Entry nel linguaggio di GTK, una label ed un pulsante)
---- completo.glade -----------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="main_window">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">4</property>
<property name="margin_bottom">4</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkEntry" id="txt1">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="lbl1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Etichetta</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn1">
<property name="label" translatable="yes">Ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
---------------------------------------------
nel codice go si carica il file completo.glade
Si tratta di una piccola modifica del codice degli esempi che si trovano su GitHub
Gli eventi possono essere creati (connessi) sia nel codice sia all;'interno dei segnali di Glade...in questo caso sono tutti contenuti nel codice applicazione. In ogni caso se si puo' associare in Glade un segnnale di nome "pressione" all'evento di click del pulsante
package main
import (
"errors"
"fmt"
"log"
"os"
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
)
const appId = "com.github.gotk3.gotk3-examples.glade"
func main() {
// Create a new application.
application, err := gtk.ApplicationNew(appId, glib.APPLICATION_FLAGS_NONE)
errorCheck(err)
// Connect function to application startup event, this is not required.
application.Connect("startup", func() {
log.Println("application startup")
})
// Connect function to application activate event
application.Connect("activate", func() {
log.Println("application activate")
// Get the GtkBuilder UI definition in the glade file.
// builder, err := gtk.BuilderNewFromFile("ui/example.glade")
builder, err := gtk.BuilderNewFromFile("/home/luca/glade/completo.glade")
errorCheck(err)
obj, _ := builder.GetObject("txt1")
entry1 := obj.(*gtk.Entry)
obj2, _ := builder.GetObject("btn1")
button1 := obj2.(*gtk.Button)
obj3, _ := builder.GetObject("lbl1")
label1 := obj3.(*gtk.Label)
button1.Connect("clicked", func() {
text, err := entry1.GetText()
if err == nil {
label1.SetText(text)
}
})
// Map the handlers to callback functions, and connect the signals
// to the Builder.
signals := map[string]interface{}{
"on_main_window_destroy": onMainWindowDestroy,
//"pressione": clickedTestButton,
}
builder.ConnectSignals(signals)
// Get the object with the id of "main_window".
obj4, err := builder.GetObject("main_window")
errorCheck(err)
// Verify that the object is a pointer to a gtk.ApplicationWindow.
win, err := isWindow(obj4)
errorCheck(err)
// Show the Window and all of its components.
win.Show()
application.AddWindow(win)
})
// Connect function to application shutdown event, this is not required.
application.Connect("shutdown", func() {
log.Println("application shutdown")
})
// Connect function to application shutdown event, this is not required.
application.Connect("pressione", func() {
log.Println("pressione")
fmt.Println("pressione")
})
// Launch the application
os.Exit(application.Run(os.Args))
}
func isWindow(obj glib.IObject) (*gtk.Window, error) {
// Make type assertion (as per gtk.go).
if win, ok := obj.(*gtk.Window); ok {
return win, nil
}
return nil, errors.New("not a *gtk.Window")
}
func errorCheck(e error) {
if e != nil {
// panic for any errors.
log.Panic(e)
}
}
/*
func clickedTestButton() {
fmt.Println("Testclick")
//headerBar.SetTitle("New Title!!")
}*/
// onMainWindowDestory is the callback that is linked to the
// on_main_window_destroy handler. It is not required to map this,
// and is here to simply demo how to hook-up custom callbacks.
func onMainWindowDestroy() {
log.Println("onMainWindowDestroy")
}
per eseguire il programma
go run -tags pango_1_42,gtk_3_22 .
con la libreria nativa il codice e' piu' pulito. L'unico problema e' che si tratta di una libreria dichiarata ancora in alpha e che non risulta aggiornata da due anni
package main
import (
"github.com/andlabs/ui"
)
func main() {
err := ui.Main(func() {
input := ui.NewEntry()
button := ui.NewButton("Ok")
greeting := ui.NewLabel("")
box := ui.NewVerticalBox()
box.Append(ui.NewLabel("Label"), false)
box.Append(input, false)
box.Append(button, false)
box.Append(greeting, false)
window := ui.NewWindow("UI", 200, 100, false)
window.SetMargined(true)
window.SetChild(box)
button.OnClicked(func(*ui.Button) {
greeting.SetText(input.Text())
})
window.OnClosing(func(*ui.Window) bool {
ui.Quit()
return true
})
window.Show()
})
if err != nil {
panic(err)
}
}