先看下window窗口的定义,这下就明朗了,walk的窗口是结构是这样定义的
type MainWindow struct { AssignTo **walk.MainWindow //关联 Name string //窗口名 一旦设置了无法更改 Enabled Property //是否禁用 Visible Property //可视化 Font Font //字体 MinSize Size //最小化尺寸 MaxSize Size//最大化尺寸 ContextMenuItems []MenuItem //窗口菜单栏 OnKeyDown walk.KeyEventHandler //键盘按下 OnKeyPress walk.KeyEventHandler //键盘按下前的事件,不把按键的结果返回计算机。 OnKeyUp walk.KeyEventHandler //键盘抬起 OnMouseDown walk.MouseEventHandler//鼠标点下 OnMouseMove walk.MouseEventHandler //鼠标移动 OnMouseUp walk.MouseEventHandler//鼠标抬起 OnDropFiles walk.DropFilesEventHandler //拖动文件到窗口 OnSizeChanged walk.EventHandler //尺寸改变 Title string //窗口标题 Size Size //窗口正常化尺寸 DataBinder DataBinder//数据绑定 Layout Layout//窗口布局 Children []Widget //子控件wiget,包含容器,控件等。 MenuItems []MenuItem//菜单栏设置 ToolBarItems []MenuItem // Deprecated,use ToolBar instead //工具栏已经废弃,用下面的ToolBar ToolBar ToolBar }
import ( //"github.com/lxn/walk" . "github.com/lxn/walk/declarative" ) func main() { MainWindow{ Name: "demo",Title: "我是demo",MinSize: Size{300,200},}.Run() }
运行效果:
我们先分析看下walk中run方法的定义。
func (mw MainWindow) Run() (int,error) { var w *walk.MainWindow if mw.AssignTo == nil { mw.AssignTo = &w } if err := mw.Create(); err != nil { return 0,err } return (*mw.AssignTo).Run(),nil }
可以看到一直回调Run()这个方法,这说明了窗口是一直绘制的,假如我们一次调用里面的mw.Create()方法,那么窗口只是一闪而过。
因为window窗口绘制涉及到很复杂的东西,包含初始化、各种窗口消息、子类化、继承等等。无法一下讲完,研究GO语言绘制出UI才是我们的正道,否则有点舍本逐末,我们最求的是结果,无需关心底层的实现,只讲实现才是正确的选择。
一个窗口还不行,得添加个按钮,比如添加按钮后,我们点击按钮,修改按钮标题.
import ( "syscall" "unsafe" "github.com/lxn/walk" . "github.com/lxn/walk/declarative" ) func main() { var w *walk.MainWindow var a *walk.PushButton MainWindow{ AssignTo: &w,Name: "ok",Title: "我是demo",MinSize: Size{300,Layout: VBox{},//布局 Children: []Widget{ //不动态添加控件的话,在此布局或者QT设计器设计UI文件,然后加载。 PushButton{ Text: "点击我修改按钮标题",AssignTo: &a,OnClicked: func() { //update(a) 方法1。或者直接把a作为全局变量,无需传递a 。或者直接定义结构体,添加方法。 a.SendMessage(12,uintptr(0),uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("hello")))) //方法2 },},}.Run() } func update(a *walk.PushButton) { a.SetText("hello") }