常用控件集合
本章介绍并学习路线中弹窗之前(包含弹窗)的所有控件
一、认识控件
本章将要学习的控件列表如下图所示,逐一讲解使用方法;
二、预备知识
2.1 控件结构体中通用字段
- AssignTo :绑定该控件类型指针,目的是后续业务中可以控制该控件属性;
- ToolTipText :作用是当鼠标移到该控件时,会浮窗显示提示信息;
三、控件使用
3.1 TextLabel
TextLabel{
AssignTo: &myMain.TextLabel,
Text: "我是文本标签",
},
3.2 TextEdit
TextEdit{
AssignTo: &myMain.TextEdit,
Text: "我是文本框",
ReadOnly: false, // false:文本框只读 true:文本框可读可写
ColumnSpan: 9,
},
3.3 Label
Label{
AssignTo: &myMain.Label,
Text: "我是标签",
},
3.4 NumberLabel
NumberLabel{
AssignTo: &myMain.NumberLabel,
Value: float64(521), //警告:这里给的默认值,一定要强转为int64,否则NumberLabel.Create时,断言失败就是0了。
},
3.5 NumberEdit
NumberEdit{
AssignTo: &myMain.NumberEdit,
Value: float64(10), //警告:这里给的默认值,一定要强转为int64,否则NumberLabel.Create时,断言失败就是0了。
},
3.6 LineEdit
LineEdit{
AssignTo: &myMain.LineEdit,
Text: "我是行编辑",
TextColor: walk.Color(walk.RGB(100, 100, 100)),
Enabled: true, // false:文本框只读 true:文本框可读可写
PasswordMode: true, //可选,输入内容后密文,显示******
MaxLength: 5, //设置最大输入字符数
TextColor:walk.RGB(218, 8, 9),//设置文本颜色
ReadOnly: true,//设置文本只读
},
// 获取输入框内容
myMain.LineEdit.Text()
3.7 CheckBox
CheckBox{
AssignTo: &myMain.CheckBox,
Text: "复选框",
ToolTipText: "单选、复选框",
Checked: true, //注意:true 默认选中,false:默认未选
},
// 在事件触发接口中,实现多个单选框使用时逻辑:
func OK_Clicked() {
switch {
case myMain.CheckBox_english.Checked():
le.SetText("英语系")
case myMain.CheckBox_sport.Checked():
le.SetText("体育系")
case myMain.CheckBox_maths.Checked():
le.SetText("数学系")
}
}
3.8 PushButton
PushButton{
Text: "按钮",
OnClicked: func() {
walk.MsgBox(nil, "我是弹框", "测试button", walk.MsgBoxIconInformation)
// 此处实现你想要做的业务
// ......
},
},
3.9 ComboBox
第一种,简单用法,默认显示选中苹果
ComboBox{
AssignTo: &myMain.ComboBox,
Model: []string{"苹果", "草莓", "香蕉"}, //下拉菜单数据源
CurrentIndex: 0, // 默认显示model数据的索引
// 选中下拉菜单中某个选项时触发
OnCurrentIndexChanged: func() {
// 打印最新索引id
logger.Println(myMain.ComboBox.CurrentIndex())
},
},
第二种,绑定数据
animal := new(Animal)
Composite{
DataBinder: DataBinder{
AssignTo: &db,
Name: "animal",
DataSource: animal,
ErrorPresenter: ToolTipErrorPresenter{},
},
Layout: Grid{Columns: 2},
Children: []Widget{
ComboBox{
// 和DataBinder.DataSource字段关联,当前则是关联animal.SpeciesId字段,即选择下拉菜单中id对应值刷新到DataBinder.DataSource字段中
// SelRequired{} 作用是约束该选项不允许为空,否则会强制提示;
Value: Bind("SpeciesId", SelRequired{}),
BindingMember: "Id", // 绑定数据字段名(和Model字段关联)
DisplayMember: "Name", // 显示数据字段名(和Model字段关联)
Model: KnownSpecies(),
},
PushButton{
AssignTo: &acceptPB,
Text: "OK",
// 手动更新绑定数据,点击OK按钮时才更新
OnClicked: func() {
walk.MsgBox(nil, "修改前", fmt.Sprintf("%+v", animal), walk.MsgBoxIconInformation)
// 此处手动提交更新绑定数据
if err := db.Submit(); err != nil {
log.Print(err)
return
}
walk.MsgBox(nil, "结果", fmt.Sprintf("%+v", animal), walk.MsgBoxIconInformation)
},
},
},
},
type Animal struct {
Name string
ArrivalDate time.Time
SpeciesId int
Speed int
Sex Sex
Weight float64
PreferredFood string
Domesticated bool
Remarks string
Patience time.Duration
}
type Species struct {
Id int
Name string
}
func KnownSpecies() []*Species {
return []*Species{
{1, "Dog"},
{2, "Cat"},
{3, "Bird"},
{4, "Fish"},
{5, "Elephant"},
}
}
3.10 RadioButton
RadioButton{
AssignTo: &myMain.RadioButton,
Text: "单选按钮",
ToolTipText: "单选按钮",
},
3.11 RadioButtonGroup
// 首先定义该按钮要绑定的数据结构
type Fool struct {
Bar string
Baz int
}
// 声明一个变量
fooBox := Fool{"box", 0}
Composite{
Layout: HBox{},
DataBinder: DataBinder{
DataSource: &foo, // 变量名 此处必须是指针
Name: "foo",// 变量名
AutoSubmit: true,// 自动提交,意思是选中后,变量fooBox.Baz 字段值会自动更新;
// 每次操作选中后,自动触发该接口调用,所以对应业务就可以在这里实现,案例中只是打印了变量内容;
OnSubmitted: func() {
logger.Printf("foo:%v", foo)
},
},
Children: []Widget{
RadioButtonGroup{
DataMember: "Baz",//指定绑定变量中的字段名,和上面的DataBinder是配套的;
Buttons: []RadioButton{
RadioButton{
Name: "oneRB",
Text: "one", //界面显示的选项名
Value: 1, // 选择选项后的值,此处绑定的是fooBox.Baz字段值
},
RadioButton{
Name: "twoRB",
Text: "two",
Value: 2,
},
RadioButton{
Name: "threeRB",
Text: "three",
Value: 3,
},
},
},
},
},
3.12 RadioButtonGroupBox
用法逻辑:
1. 根据业务创建自己的结构体,例如
type Fool struct
Bar string
Baz int
}
2. 创建一个结构体变量fooBox ;
3. 将该结构体变量中的字段和按钮进行绑定,比如Baz字段;
4.当点击按钮选中时,变量fooBox 的字段值就会被更新;
// 首先定义该按钮要绑定的数据结构
type Fool struct {
Bar string
Baz int
}
// 声明一个变量
fooBox := Fool{"box", 0}
// 创建控件
Composite{
Layout: HBox{},
// 绑定数据
DataBinder: DataBinder{
DataSource: &fooBox, //变量名,此处必须是指针
Name: "fooBox",//变量名
AutoSubmit: true, //自动提交,意思是选中后,变量fooBox.Baz 字段值会自动更新;
// 每次操作选中后,自动触发该接口调用,所以对应业务就可以在这里实现,案例中只是打印了变量内容;
OnSubmitted: func() {
logger.Printf("foo:%v", fooBox)
},
},
Children: []Widget{
RadioButtonGroupBox{
Title: "box",//组框的名称,界面会显示
Layout: HBox{},
DataMember: "Baz", //指定绑定变量中的字段名,和上面的DataBinder是配套的;
Buttons: []RadioButton{
{Text: "Male", Value: 5},// Text按钮名称,Value按钮对应点击后的值
{Text: "Female", Value: 6},
{Text: "Hermaphrodite", Value: 7},
},
},
},
},
3.13 TableView
追加:表格记录右键子菜单功能
mdTableView := NewStudentModel()
Composite{
Layout: HBox{},
// 该节点作用是添加表格右键子菜单
ContextMenuItems: []MenuItem{
Action{
Text: "I&nfo",
// OnTriggered: mw.tv_ItemActivated,
},
Action{
Text: "E&xit",
OnTriggered: func() {
//此处实现逻辑
// mw.Close()
},
},
},
Children: []Widget{
TableView{
AssignTo: &myMain.TableView,
ToolTipText: "表格数据",
ColumnsOrderable: true, // 列支持排序
MultiSelection: true, // 可以同时选中多行
// 表格内容列
Columns: []TableViewColumn{
{Title: "序号"},
{Title: "姓名"},
{Title: "年龄"},
{Title: "录入时间", Width: 200}},//可单独指定某列宽度
Model: mdTableView,//绑定数据源
},
},
},
type StudentInfo struct {
SeqNo int // 序号
Name string // 名字
Age int // 年龄
CreateTime string // 录入时间
checked bool //是否被选中,下面SetChecked接口调用时设置
}
type StudentModel struct {
walk.TableModelBase
walk.SorterBase
sortColumn int
sortOrder walk.SortOrder
items []*StudentInfo // 存放数据,后续通过修改该字段内容,实现界面的数据刷新
}
func NewStudentModel() *StudentModel {
m := new(StudentModel)
m.ResetRows()
return m
}
// 用户自己定义的,生成测试数据
func (m *StudentModel) ResetRows() {
m.items = make([]*StudentInfo, 10, 20)
// 注意,这里一定不能写成m.items = make([]*StudentInfo, 20),否则会panic,除了当前写法,也可以把for循环长度改为20即可
for i := 0; i < 10; i++ {
m.items[i] = &StudentInfo{i, "xiaoming", i + 2, "2020-10-10 10:10:10", false}
}
m.PublishRowsReset() //手动触发界面刷新,数据变更时根据需要调用。
}
// 控件刷新时调用
func (m *StudentModel) RowCount() int {
logger.Println("len:", len(m.items), cap(m.items))
return len(m.items)
}
// 当TableView需要为给定单元格显示文本时,由TableView调用
func (m *StudentModel) Value(row, col int) interface{} {
item := m.items[row]
switch col {
case 0:
return item.SeqNo
case 1:
return item.Name
case 2:
return item.Age
case 3:
return item.CreateTime
}
panic("unexpected col")
}
// 由TableView调用以检索是否选中了给定行。
func (m *StudentModel) Checked(row int) bool {
return m.items[row].checked
}
// 当用户切换给定行的复选框时由TableView调用
func (m *StudentModel) SetChecked(row int, checked bool) error {
m.items[row].checked = checked
return nil
}
// 由TableView调用以对模型进行排序
func (m *StudentModel) Sort(col int, order walk.SortOrder) error {
logger.Println("sort..............", m.items)
return nil
}
3.14 ListBox
listBoxMd := NewEnvModel()
ListBox{
AssignTo: &myMain.ListBox,
ToolTipText: "列表控件",
Model: listBoxMd,
OnItemActivated: func() {
name := listBoxMd.items[myMain.ListBox.CurrentIndex()].name
value := listBoxMd.items[myMain.ListBox.CurrentIndex()].value
walk.MsgBox(nil, name, value, walk.MsgBoxIconInformation)
},
},
type EnvModel struct {
walk.ListModelBase
items []EnvItem
}
type EnvItem struct {
name string
value string
}
func NewEnvModel() *EnvModel {
// 初始化列表内容,此处功能时读取电脑环境变量,将名字以列表形式显示,单据某条时,弹出对应的环境变量;
env := os.Environ()
m := &EnvModel{items: make([]EnvItem, len(env))}
for i, e := range env {
j := strings.Index(e, "=")
if j == 0 {
continue
}
name := e[0:j]
value := strings.Replace(e[j+1:], ";", "\r\n", -1)
m.items[i] = EnvItem{name, value}
}
return m
}
// 获取节点数,即有多少条数据,由ListBox调用
func (m *EnvModel) ItemCount() int {
return len(m.items)
}
// 显示每一行时由ListBox调用
func (m *EnvModel) Value(index int) interface{} {
if m.items[index].name == "" {
return "null"
}
return m.items[index].name
}
3.15 Slider
// 当前实现的是,拖动滑动条,在指定NumberEdit控件中显示实时数据
Slider{
AssignTo: &myMain.Slider,
ToolTipText: "滑动条",
MaxValue: 1000, // 滑动条最大值
MinValue: 0, // 滑动条最小值
Orientation: Horizontal, // 滑动条方向,垂直或者水平,当前水平
// 点击某一个位置时触发
OnValueChanged: func() {
v := myMain.Slider.Value()
myMain.NumberEdit.SetValue(float64(v))
},
// 拖动滑动条过程即触发
OnMouseMove: func(x, y int, button walk.MouseButton) {
v := myMain.Slider.Value()
myMain.NumberEdit.SetValue(float64(v))
},
},
3.16 StatusBarItem
StatusBarItem{
AssignTo: &myMain.StatusBarItem,
Icon: icon1, // 可选 显示图标
Text: "click", // 显示名字
Width: 80, // 宽度
//点击该状态栏是,图标来回切换
OnClicked: func() {
if myMain.StatusBarItem.Text() == "click" {
myMain.StatusBarItem.SetText("again")
myMain.StatusBarItem.SetIcon(icon2)
} else {
myMain.StatusBarItem.SetText("click")
myMain.StatusBarItem.SetIcon(icon1)
}
},
},
StatusBarItem{
Text: "left",
ToolTipText: "no tooltip for me",
},
StatusBarItem{
Text: "\tcenter",
},
StatusBarItem{
Text: "\t\tright",
},
StatusBarItem{
Icon: icon1,
ToolTipText: "An icon with a tooltip",
},