Go GUI controls and signals

Keywords: Go github Programming

control

Control Brief

Control is the encapsulation of data and methods. Control has its own properties and methods. Property refers to the characteristics of the control. Method refers to some simple and visible functions of the control. For example, the button is a control. The button is square, with a picture inside. This is the appearance property we can see. At the same time, the button has the function of being pressed.

GTK controls are mainly divided into two categories: container controls and non container controls.

Container control: it can hold other controls. We can understand it as a box. The box is used to hold things. Container controls can be divided into two categories: one can only hold one control, such as window and button; the other can hold multiple controls, such as layout controls.
Non container control: it cannot hold other controls, such as label and row editing.

package main

import (
    "os"

    "github.com/mattn/go-gtk/gtk"
)

func main() {
    gtk.Init(&os.Args) //Environment initialization

    //--------------------------------------------------------
    // main window
    //--------------------------------------------------------
    window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL) //create a window
    window.SetPosition(gtk.WIN_POS_CENTER)       //Set window center
    window.SetTitle("GTK Go!")                   //Set title
    window.SetSizeRequest(300, 200)              //Set the width and height of the window

    //--------------------------------------------------------
    // GtkFixed
    //--------------------------------------------------------
    layout := gtk.NewFixed() //Create a fixed layout

    //--------------------------------------------------------
    // GtkButton
    //--------------------------------------------------------
    b1 := gtk.NewButton() //New button
    b1.SetLabel("^_@")    //Set contents
    //b1.SetSizeRequest(100, 50) / / set button size

    b2 := gtk.NewButtonWithLabel("@_~") //Create a new button and set the content at the same time
    b2.SetSizeRequest(100, 50)          //Set button size

    //--------------------------------------------------------
    // Add layout, add container
    //--------------------------------------------------------
    window.Add(layout) //Add layout to main window

    layout.Put(b1, 0, 0)    //Set the location of the button in the container
    layout.Move(b1, 50, 50) //To move the position of the button, you must first put it, and then move it

    layout.Put(b2, 50, 100)

    window.ShowAll() //Show all controls

    gtk.Main() //Main event loop, waiting for user action
}

//func (v *Fixed) Put(w IWidget, x, y int)
//Function: fixed layout container add control
//Parameters:
//    widget: control to add
//    x, y: coordinate of the starting point of the control placement position

signal

GTK uses signal and callback functions to process events, messages or signals from outside the window. When a signal occurs, the program automatically calls the callback function that connects (registers) the signal.

Learning GUI programming, we will often come into contact with the term "signal". The "signal" in GTK is actually a software interrupt. "Interruption" is often encountered in our life. For example, when I am playing a game in my room, suddenly the express delivery person comes and "interrupts" me who is playing the game. I go to sign for the express delivery (processing the interruption). After processing, I will continue to play my game. The "signal" in GTK belongs to such an "interrupt". When the user presses the button, an "interrupt" will be generated, which is equivalent to a signal, and then such an "interrupt task" (the experience in the program is to call a function).

"Signal" in GTK can be regarded as a sign of interruption. For example, the sign of pressing the button is "pressed" and the sign of releasing the button is "released". These signs are equivalent to the keyword of go language. When we use them, we must write them completely according to their names. It should be noted that the signal signs of each control are not necessarily the same. For example, there is a "pressed" signal in the button (GtkButton), but there is no such signal in the window (GtkWindow). The specific signal of each control should be determined by checking the help documents.
Signal identification trigger condition

Triggered when the "clicked" button is pressed
Triggered when the "pressed" button is pressed
Triggered when the "released" button is released

package main

import (
    "fmt"
    "os"

    "github.com/mattn/go-gtk/glib"
    "github.com/mattn/go-gtk/gtk"
)

//Callback function of button b1 signal processing
func HandleButton(ctx *glib.CallbackContext) {
    arg := ctx.Data()   //Get the parameter passed by the user, which is an empty interface type
    p, ok := arg.(*int) //Type Asserts
    if ok {             //If ok is true, the type assertion is correct
        fmt.Println("*p = ", *p) //The parameter passed by the user is & TMP, which is the address of a variable
        *p = 250                 //Memory pointed to by operation pointer
    }

    fmt.Println("Button b1 Be pressed")

    //gtk.MainQuit() / / close gtk program
}

func main() {
    gtk.Init(&os.Args) //Environment initialization

    //--------------------------------------------------------
    // main window
    //--------------------------------------------------------
    window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL) //create a window
    window.SetPosition(gtk.WIN_POS_CENTER)       //Set window center
    window.SetTitle("GTK Go!")                   //Set title
    window.SetSizeRequest(300, 200)              //Set the width and height of the window

    //--------------------------------------------------------
    // GtkFixed
    //--------------------------------------------------------
    layout := gtk.NewFixed() //Create a fixed layout

    //--------------------------------------------------------
    // GtkButton
    //--------------------------------------------------------
    b1 := gtk.NewButton() //New button
    b1.SetLabel("^_@")    //Set contents
    //b1.SetSizeRequest(100, 50) / / set button size

    b2 := gtk.NewButtonWithLabel("@_~") //Create a new button and set the content at the same time
    b2.SetSizeRequest(100, 50)          //Set button size

    //--------------------------------------------------------
    // Add layout, add container
    //--------------------------------------------------------
    window.Add(layout) //Add layout to main window

    layout.Put(b1, 0, 0)    //Set the location of the button in the container
    layout.Move(b1, 50, 50) //To move the position of the button, you must first put it, and then move it

    layout.Put(b2, 50, 100)

    //--------------------------------------------------------
    // signal processing
    //--------------------------------------------------------
    //Press the button to trigger "pressed" automatically, call HandleButton automatically, and pass & TMP to HandleButton at the same time
    tmp := 10
    b1.Connect("pressed", HandleButton, &tmp)

    //Callback function is anonymous function, recommended writing method
    //Press the button to trigger "pressed" automatically to call the anonymous function,
    b2.Connect("pressed", func() {

        fmt.Println("b2 Be pressed")
        fmt.Println("tmp = ", tmp)

    }) //Note:} and) are on the same line

    window.ShowAll() //Show all controls

    gtk.Main() //Main event loop, waiting for user action
}

//func (v *Widget) Connect(s string, f interface{}, datas ...interface{}) int
//Function: signal registration
//Parameters:
//    v: the signal sender can think that the control we operate, such as pressing the button, is the button pointer
//    s: signal sign, such as "pressed"
//    f: the name of the callback function,
//    Data: the parameter passed to the callback function, although it is variable, can only pass one parameter. The purpose of variable parameter is to let users have multiple choices (parameter can be passed or not)
//Return value:
//    Flag to register function

Simple use of glade

package main

import (
    "fmt"
    "os"

    "github.com/mattn/go-gtk/gtk"
)

func main() {
    gtk.Init(&os.Args)

    builder := gtk.NewBuilder()       //New builder
    builder.AddFromFile("test.glade") //Read the glade file

    // Get the window control pointer. Note that "window1" should match the flag name in the glade
    window := gtk.WindowFromObject(builder.GetObject("window1"))
    b1 := gtk.ButtonFromObject(builder.GetObject("123456"))        //Get button 1
    b2 := gtk.ButtonFromObject(builder.GetObject("togglebutton1")) //Get button 2

    //signal processing
    b1.Connect("clicked", func() {
        //Get button content
        fmt.Println("button txt = ", b1.GetLabel())
    })

    b2.Connect("clicked", func() {
        //Get button content
        fmt.Println("button txt = ", b2.GetLabel())
        gtk.MainQuit() //close window
    })

    //Press the window close button to automatically trigger the "destroy" signal
    window.Connect("destroy", gtk.MainQuit)

    window.ShowAll()

    gtk.Main()
}

//It can be simply divided into two steps:

//1) read the glade file

////Create GtkBuilder object, and GtkBuilder declares in < GTK / gtk. H >

//GtkBuilder *builder = gtk_builder_new();

////Read the information of the test.glade file and save it in the builder pointer variable

//gtk_builder_add_from_file(builder, "./test.glade", NULL);

//2) get the control in the glade file

////Get the window control pointer. Note that "window1" should match the flag name in the glade

//GtkWidget *window = GTK_WIDGET(gtk_builder_get_object (builder, "window1"));

Posted by weekender on Wed, 27 Nov 2019 13:33:41 -0800