GolangGUI編程


GUI編程

互聯網上已經涌現出不少成熟、好用的第三方GUI界面庫。
https://github.com/avelino/awesome-go#gui

GTK2

GTK+ 是一種面向對象式的API(applicationprogramming interface)。Glib 是GTK+的基礎,而這種“面向對象系統”正是由“Glib”來提供的。GTK+ 是一種函數庫是用來幫助制作圖形交互界面的,同時遵循 LGPL 許可證。
GTK2:https://github.com/mattn/go-gtk

  • 工具:Glade
  1. 布局

常用控件選擇區:列舉了常用的控件,常用的有三類:頂層(主窗口等),容器(各種布局容器等),控制和顯示(按鈕、便簽、圖片控件等)

界面編輯區:把控件拖放在這進行進行相應的布局

控件監視區:能夠看到界面上所有的控件,同時,選中這個控件,可以看到這個控件的具體類型

屬性編輯區:編輯選中控件的常用屬性,如窗口設置標題、窗口類型、屏幕上顯示位置等。

工具欄:常用的有以下幾個按鈕

新建:新建一個glade文件
打開:打開一個已經存在的glade文件
保存:保存一個glade文件
選擇:按了這個按鈕, 才能選擇控件
拖拽調整大小:按了這個按鈕,才能移動控件的位置,改變控件的大小

  1. Glade的操作

選擇控件時,一定要先按工具欄的“選擇”按鈕
操作時,支持撤銷(Ctrl+z)和恢復(Ctrl+y)等window的快捷鍵

操作的流程和布局的過程是一致的:

1.選擇主窗口,根據需要設置窗口的相應屬性
2. 選擇布局容器
3. 根據需要選擇相應的控件,根據需要設置控件的相應屬性

  • 環境搭建(windows)
  1. 下載安裝msys2

官方網址:http://www.msys2.org/

  1. 安裝所需軟件
    安裝gtk3:
    pacman -S mingw-w64-x86_64-gtk3

    安裝gtk2:
    pacman -S mingw-w64-x86_64-gtk2

    安裝glade
    pacman -S mingw-w64-x86_64-glade

    安裝幫助文檔
    pacman -S mingw-w64-x86_64-devhelp

    安裝MinGW
    pacman -S mingw-w64-x86_64-toolchain base-devel
  1. 配置環境變量
    配置:
    PATH:
    C:\msys64\usr\bin
    C:\msys64\mingw64\bin

    測試:
    pkg-config --cflags gtk+-2.0
    make -v
  1. 下載依賴
    //官方
    # go get github.com/mattn/go-gtk/gtk

    //國內  放在GOPATH目錄src下
    # git clone  https://github.com/mattn/go-gtk
    # cd go-gtk
    # make install
    # make example
    # ./example/demo/demo
  1. 運行官方demo
    # cd $GOPATH/github.com/mattn/go-gtk/example/demo
    # go build demo.go
    # demo.exe

  1. 導入依賴
    import (
        "github.com/mattn/go-gtk/gdkpixbuf"
        "github.com/mattn/go-gtk/glib"
        "github.com/mattn/go-gtk/gtk"
    )
  • 控件

控件是對數據和方法的封裝。控件有自己的屬性和方法。屬性是指控件的特征。方法是指控件的一些簡單而可見的功能

GTK中控件主要分為兩類:容器控件,非容器控件。

  1. 容器控件:它可以容納別的控件,我們可以理解為盒子,盒子拿來裝東西。容器控件又分為兩類,一類只能容納一個控件,如窗口,按鈕;另一類能容納多個控件,如布局控件。
  2. 非容器控件:它不可以容納別的控件,如標簽、行編輯。
Put:
func (v *Fixed) Put(w IWidget, x, y int)
功能:固定布局容器添加控件
參數:
    widget:要添加的控件
    x, y:控件擺放位置的起點坐標

ShowAll:
func (v *Widget) ShowAll()
功能:顯示所有的控件,如果窗口放入一個容器,這時,容器上的所有控件也會跟着顯示。
package main

import (
    "os"
    "github.com/mattn/go-gtk/gtk"
)

func main() {
    gtk.Init(&os.Args)
    /*
        gtk.Init(&os.Args):所有 GTK應用程序都要調用該函數,
        而且必須在控件定義之前使用,它為我們設置一些缺省值
        ( 例如視覺和顏色 )映射這個函數將函數庫初始化,設置
        缺省的信號處理函數,並檢查通過命令行傳遞給應用程序的
        參數,自動完成一些必要的初始化工作。
    */

    //--------------------------------------------------------
    // 主窗口
    //--------------------------------------------------------
    window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
    /*
        gtk.NewWindow(gtk.WINDOW_TOPLEVEL):創建一個窗口並
        返回這個窗口的控件指針。gtk.WINDOW_TOPLEVEL指明窗口
        的類型為最上層的主窗口(則帶邊框的窗口),它最常用。
    */
    window.SetPosition(gtk.WIN_POS_CENTER)       //設置窗口居中顯示
    window.SetTitle("Minor Six Ren")                   //設置標題
    window.SetSizeRequest(300, 200)              //設置窗口的寬度和高度

    //--------------------------------------------------------
    // GtkFixed
    //--------------------------------------------------------
    layout := gtk.NewFixed() //創建固定布局

    //--------------------------------------------------------
    // GtkButton
    //--------------------------------------------------------
    b1 := gtk.NewButton() //新建按鈕
    b1.SetLabel("^_@")    //設置內容
    //b1.SetSizeRequest(100, 50) //設置按鈕大小

    b2 := gtk.NewButtonWithLabel("@_~") //新建按鈕,同時設置內容
    b2.SetSizeRequest(100, 50)          //設置按鈕大小

    //--------------------------------------------------------
    // 添加布局、添加容器
    //--------------------------------------------------------
    window.Add(layout) //把布局添加到主窗口中

    layout.Put(b1, 0, 0)    //設置按鈕在容器的位置
    layout.Move(b1, 50, 50) //移動按鈕的位置,必須先put,再用move

    layout.Put(b2, 50, 100)

    window.ShowAll() //顯示所有的控件
    /*
        window.Show():顯示上一步創建的窗口控件。
        window.ShowAll():顯示所有的控件,如果窗口放入一個容器,這時,容器上的所有控件也會跟着顯示

在這個簡單例子里,所有事件都被忽略。用鼠標點擊窗口右上角的“×”按鈕也不能將窗口關閉。可通過任務管理器關閉。
    */

    gtk.Main() //主事件循環,等待用戶操作
    /*
        gtk.Main():它是在每個Gtk應用程序都要調用的
        函數。程序運行停在這里等待事件(如鍵盤事件或
        鼠標事件)的發生,等待用戶來操作窗口。
    */
}
  • 信號處理
    “信號”在GTK中可以認為一種中斷的標志
信號標識 觸發條件
clicked 按下按鈕時觸發
pressed 按下按鈕時觸發
released 釋放按鈕時觸發
destroy 按關閉窗口按鈕時觸發
信號注冊函數說明:

func (v *Widget) Connect(s string, f interface{}, datas ...interface{}) int
功能:信號注冊
參數:
    v: 信號發出者,可以認為我們操作的控件,如按下按鈕,這個就為按鈕指針
    s:信號標志,如"pressed"
    f:回調函數的名稱,
    datas:給回調函數傳的參數,盡管是可變參數,但是只能傳遞一個參數,可變參數的目的為了讓用戶多個選擇(可以傳參,或者不傳)
返回值:
    注冊函數的標志
    package main
    import (
        "fmt"
        "os"

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

    //按鈕b1信號處理的回調函數
    func HandleButton(ctx *glib.CallbackContext) {
        arg := ctx.Data()   //獲取用戶傳遞的參數,是空接口類型
        p, ok := arg.(*int) //類型斷言
        if ok {             //如果ok為true,說明類型斷言正確
            fmt.Println("*p = ", *p) //用戶傳遞傳遞的參數為&tmp,是一個變量的地址
            *p = 250                 //操作指針所指向的內存
        }
        fmt.Println("按鈕b1被按下")

        //gtk.MainQuit() //關閉gtk程序
    }

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

        window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
        window.SetPosition(gtk.WIN_POS_CENTER)
        window.SetTitle("GTK Go!")
        window.SetSizeRequest(300, 200)
        layout := gtk.NewFixed()

        b1 := gtk.NewButton()
        b1.SetLabel("按鈕1")

        b2 := gtk.NewButtonWithLabel("按鈕2")
        b2.SetSizeRequest(100, 50)

        window.Add(layout)
        layout.Put(b1, 0, 0)
        layout.Move(b1, 50, 50) //移動按鈕的位置,必須先put,再用move
        layout.Put(b2, 50, 100)

        //--------------------------------------------------------
        // 信號處理
        //--------------------------------------------------------
        //按鈕按下自動觸發"pressed",自動調用HandleButton, 同時將 &tmp 傳遞給HandleButton
        tmp := 10
        b1.Connect("pressed", HandleButton, &tmp)

        //回調函數為匿名函數,推薦寫法
        //按鈕按下自動觸發"pressed",自動調用匿名函數,
        b2.Connect("pressed", func() {
            fmt.Println("b2被按下")
            fmt.Println("tmp = ", tmp)
        }) //注意:}和)在同一行

        window.ShowAll()

        gtk.Main()
    }

GTK+3

GTK+3:https://github.com/gotk3/gotk3

    import (
        "github.com/gotk3/gotk3/glib"
        "github.com/gotk3/gotk3/gtk"
    )
package main

import (
    "fmt"
    "github.com/gotk3/gotk3/glib"
    "github.com/gotk3/gotk3/gtk"
    "log"
    "os"
)

//這部分是相同的
func main() {
    const appId = "com.guidemo.example"
    //每個gtk3程序都需要一步
    app, err := gtk.ApplicationNew(appId, glib.APPLICATION_FLAGS_NONE)
    /*
        gtk.ApplicationNew()接受兩個參數一個是 應用標識,其一般
        使用你域名的倒序形式。另一個是GApplicationFlags,其為了
        滿足你對應用的特定需求。通常就像實例代碼一樣寫
        glib.APPLICATION_FLAGS_NONE就可以了。
    */

    if err != nil {
        log.Fatal("Could not create application.", err)
    }

    //為activate事件綁定函數, activate會在程序啟動時觸發,也就是app.Run()時
    app.Connect("activate", func() {
        onActivate(app)
    } )

    //運行gtkApplication
    app.Run(os.Args)
}


func onActivate(application *gtk.Application) {
    appWindow, err := gtk.ApplicationWindowNew(application) //創建window控件
    if err != nil {
        log.Fatal("Could not create application window.", err)
    }
    //設置窗口屬性
    appWindow.SetTitle("Basic Application.")
    appWindow.SetDefaultSize(400, 400)

    buttonBox, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 2)     //以水平布局創建一個容器, 第二個參數是其中控件的像素間隔
    if err != nil {
        log.Fatal(err)
    }
    appWindow.Add(buttonBox)    //將布局添加到window中

    button, err := gtk.ButtonNewWithLabel("Hello World")        //創建一個按鈕
    if err != nil {
        log.Fatal(err)
    }
    buttonBox.Add(button)       //將按鈕添加到box容器中

    button.Connect("clicked", func() {  //讓我們為按鈕點擊添加一個函數,每次點擊都會在命令行輸出Hello World
        fmt.Println("Hello World")
        appWindow.Destroy()     //摧毀窗口
    })


    appWindow.ShowAll()     //與Show()不同在於,它會輸出Window中的子控件。你可以修改,查看不同的效果
}

QT

QT: https://github.com/therecipe/qt
參考:https://github.com/therecipe/qt/wiki/Installation

  • 安裝
  1. 安裝完整的Qt5在$HOME目錄下
    https://download.qt.io/official_releases/online_installers/

  2. 配置Qt的環境

# ~/.bash_profile
# therecipe/qt 需要的環境變量
export QT_DIR='/home/用戶名/Qt5.11.1' # 安裝Qt的目錄
export QT_VERSION='5.11.1'           # Qt的版本號
export QT_DEBUG=false                # 是否啟用debug
export QT_STUB=false                 # 內存低於2Gb或32位系統才需要設置true

# go1.10 cgo environments 使用go1.10時需要的設置
export CGO_CXXFLAGS_ALLOW=".*"
export CGO_LDFLAGS_ALLOW=".*"
export CGO_CFLAGS_ALLOW=".*"
  1. 補全依賴:

g++5.0+以及一些OpenGL的依賴

# Debian/Ubuntu的安裝命令
sudo apt-get -y install build-essential libglu1-mesa-dev libpulse-dev libglib2.0-dev

# Fedora/RHEL/CentOS
sudo yum -y groupinstall "C Development Tools and Libraries"
sudo yum -y install mesa-libGLU-devel gstreamer-plugins-base pulseaudio-libs-devel glib2-devel

# openSUSE
sudo zypper -n install -t pattern devel_basis

# Arch Linux
sudo pacman -S base-devel

安裝qt-tools:

go get -u -v github.com/therecipe/qt/cmd/...

安裝bindings,記住遠離sudo!!! (時間較久)

$GOPATH/bin/qtsetup

不能直接使用go build,因為qt使用了moc技術(元對象編譯器),對於一些Qt的擴展語法需要進行額外的處理

qtdeploy build [target] [path/to/your/project]

說明:
target是指定的目標平台,編譯完成后的程序將可以在target指定的平台上運行。

    如果也可以將target設為desktop,qtdeploy將會根據本地環境選擇相對應的target。以下是部分可用的target選項:
                    desktop
                    windows
                    linux
                    android
                    android-emulator
                    ios
                    ios-simulator
                    sailfish
                    sailfish-emulator
                    rpi1
                    rpi2
                    rpi3


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM