找了很長時間go的gui庫,試了gtk,准備試qt的時候發現了這個qml庫,試了下很好用。 ##准備工作 **1、Go 1.2RC1** go的版本應該不能低於這個,我是在1.2RC發布當天升級后發現的qml,並測試的。 **2、qml** 項目主頁 https://github.com/niemeyer/qml 目前還是alpha版。 項目主頁里面有各個平台的安裝方法 裝好后會順帶把qtcreator的ubuntu sdk plugin也給裝上。 然后運行qml的示例程序 github.com/niemeyer/qml/examples/particle  ##Go qml 這里嘗試寫一個簡單的登錄窗口  **1、編寫qml** 打開ubuntu sdk creator,設置下編譯環境  在 tools -> options 中 build & run 條目中找到 qt versions,然后添加qmake的路徑 32-bit: /usr/lib/i686-linux-gnu/qt5/bin/qmake 64-bit: /usr/lib/x86_64-linux-gnu/qt5/bin/qmake 然后創建一個qml項目,這里可以嘗試創建一些示例項目,這里我選擇了 qt quick2 ui。 他會創建3個文件,一個工程文件,一個源碼文件,還有一個與當前用戶有關的xml。 首先修改工程文件,加入ubuntu sdk的import路徑。 修改`qmlproject`后綴名的文件,在最后面`List of plugin directories passed to QML runtime`注釋下面加入幾行: /* List of plugin directories passed to QML runtime */ importPaths: [ "." ,"/usr/bin","/usr/lib/x86_64-linux-gnu/qt5/qml" ] 然后編輯`qml`后綴的UI文件: // 這里用到了quick2和ubuntu sdk的模塊 import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 MainView { id: root objectName: "mainView" applicationName: "LoginWindow" width: units.gu(50) height: units.gu(30) Page { title: "Login Window" objectName: "mainPage" Column { anchors.leftMargin: units.gu(2) anchors.rightMargin: units.gu(2) anchors.topMargin: units.gu(2) anchors.bottomMargin: units.gu(2) anchors.fill: parent spacing: units.gu(3) width: parent.width Item { anchors.left: parent.left height: txtName.height anchors.right: parent.right Label { id: lblUsername width: units.gu(7) anchors.verticalCenter: txtName.verticalCenter text: "User Name" } TextField { id: txtName anchors.left: lblUsername.right width: parent.width - lblUsername.width - units.gu(4) anchors.leftMargin: units.gu(4) objectName: "txtName" placeholderText: "type your username" //焦點變更事件 onFocusChanged: { if(focus){ //當獲得焦點時就用js控制台輸出,qml會把它默認轉到綁定語言的控制台標准輸出 console.log("qml: txtName focused") } } onTextChanged: { console.log("qml: " + txtName.text) //goObject將會被注入,它是一個go對象 //這里要注意,go對象的屬性或方法在go層面必須是暴露的 //但在qml中被js調用時首字母必須小寫,多試幾次就知道了 goObject.txtNameChanged(txtName.text) } } } Item { anchors.left: parent.left height: txtName.height anchors.right: parent.right Label { id: lblPasswd width: units.gu(7) anchors.verticalCenter: txtPasswd.verticalCenter text: "Password" } TextField { id: txtPasswd anchors.left: lblPasswd.right width: parent.width - lblPasswd.width - units.gu(4) anchors.leftMargin: units.gu(4) objectName: "txtPassword" echoMode: TextInput.Password text: "password" } } } } } 然后在qtcreator的build菜單中選擇run,它會用qmlscene來加載這個ui,以便調試效果。 在qtcreator中design好像有點問題,所以不建議這種所見即所得的編輯方法,這在ubuntu 13.10版本中,qt5正式引入后可能會改善。 **2、編寫main.go** 在qml項目目錄編寫main.go package main import ( "github.com/niemeyer/qml" "log" ) // 用於注入qml的go結構 type GoObject struct {} func (g *GoObject) TxtNameChanged(text string) { log.Println("go: ",text) } func main() { // 初始化qml qml.Init(nil) // 創建引擎 engine := qml.NewEngine() // 加載qml component, err := engine.LoadFile("atomqq.qml") if err != nil { panic(err) } // 獲得上下文 context := engine.Context() // 將一個go對象注入進qml上下文 goObject := GoObject{} context.SetVar("goObject", &goObject) // 創建qml窗口 window := component.CreateWindow(nil) // 獲得根控件 root := window.Root() // 根據Name屬性獲得空間 //obj := root.ObjectByName("mainPage") //obj.Set("title", "xx登錄窗口") // 顯示窗口 window.Show() // 獲得根控件的一個屬性 width := root.Int("width") log.Println(width) // 設置一個屬性的值 // 這里將窗體的寬度增加1個像素,來出發qt對窗體進行重回 // 由於使用的qml、qt5還有go在ubuntu中都不是穩定版,可能時某個里面還有bug. // qml窗體在初始化時,貌似沒有畫好,必須得手動重繪一次 root.Set("width", width + 1) // 等待退出 window.Wait() } 然后go run main.go  可以看到qml的信號被正確觸發,控制台也有輸出了