sabato 1 gennaio 2022

UI per Golang

 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)
}
}


Nessun commento:

Posta un commento

Dockerizza Flask

Un esempio semplice per inserire in un container Docker una applicazione Flask Partiamo da una semplice applicazione che ha un file app.py ...