forked from go/golangs_learn
VIVIMAN
3 years ago
10 changed files with 866 additions and 44 deletions
@ -0,0 +1,14 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"io/ioutil" |
|||
"os" |
|||
"path" |
|||
) |
|||
|
|||
func main() { |
|||
dir, _ := ioutil.ReadDir("/tmp") |
|||
for _, d := range dir { |
|||
os.RemoveAll(path.Join([]string{"tmp", d.Name()}...)) |
|||
} |
|||
} |
@ -0,0 +1,97 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"fmt" |
|||
"io" |
|||
"os" |
|||
"strings" |
|||
|
|||
"github.com/lxn/walk" |
|||
. "github.com/lxn/walk/declarative" |
|||
) |
|||
|
|||
type MyMainWindow struct { |
|||
*walk.MainWindow |
|||
edit *walk.TextEdit |
|||
} |
|||
|
|||
func main() { |
|||
mw := &MyMainWindow{} |
|||
err := MainWindow{ |
|||
AssignTo: &mw.MainWindow, //窗口重定向至mw,重定向后可由重定向变量控制控件
|
|||
Icon: "test.ico", //窗体图标
|
|||
Title: "文件选择对话框", //标题
|
|||
MinSize: Size{Width: 150, Height: 200}, |
|||
Size: Size{300, 400}, |
|||
Layout: VBox{}, //样式,纵向
|
|||
Children: []Widget{ //控件组
|
|||
TextEdit{ |
|||
AssignTo: &mw.edit, |
|||
}, |
|||
PushButton{ |
|||
Text: "打开", |
|||
OnClicked: mw.selectFile, //点击事件响应函数
|
|||
}, |
|||
PushButton{ |
|||
Text: "另存为", |
|||
OnClicked: mw.saveFile, |
|||
}, |
|||
}, |
|||
}.Create() //创建
|
|||
|
|||
if err != nil { |
|||
fmt.Fprintln(os.Stderr, err) |
|||
os.Exit(1) |
|||
} |
|||
|
|||
mw.Run() //运行
|
|||
} |
|||
|
|||
func (mw *MyMainWindow) selectFile() { |
|||
|
|||
dlg := new(walk.FileDialog) |
|||
dlg.Title = "选择文件" |
|||
dlg.Filter = "可执行文件 (*.exe)|*.exe|所有文件 (*.*)|*.*" |
|||
|
|||
mw.edit.SetText("") //通过重定向变量设置TextEdit的Text
|
|||
if ok, err := dlg.ShowOpen(mw); err != nil { |
|||
mw.edit.AppendText("Error : File Open\r\n") |
|||
return |
|||
} else if !ok { |
|||
mw.edit.AppendText("Cancel\r\n") |
|||
return |
|||
} |
|||
s := fmt.Sprintf("Select : %s\r\n", dlg.FilePath) |
|||
mw.edit.AppendText(s) |
|||
} |
|||
|
|||
func (mw *MyMainWindow) saveFile() { |
|||
|
|||
dlg := new(walk.FileDialog) |
|||
dlg.Title = "另存为" |
|||
|
|||
if ok, err := dlg.ShowSave(mw); err != nil { |
|||
fmt.Fprintln(os.Stderr, err) |
|||
return |
|||
} else if !ok { |
|||
fmt.Fprintln(os.Stderr, "Cancel") |
|||
return |
|||
} |
|||
|
|||
data := mw.edit.Text() |
|||
filename := dlg.FilePath |
|||
f, err := os.Open(filename) |
|||
if err != nil { |
|||
f, _ = os.Create(filename) |
|||
} else { |
|||
f.Close() |
|||
//打开文件,参数:文件路径及名称,打开方式,控制权限
|
|||
f, err = os.OpenFile(filename, os.O_WRONLY, 0x666) |
|||
} |
|||
if len(data) == 0 { |
|||
f.Close() |
|||
return |
|||
} |
|||
io.Copy(f, strings.NewReader(data)) |
|||
f.Close() |
|||
} |
@ -0,0 +1,163 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"fmt" |
|||
"io" |
|||
"os" |
|||
"strings" |
|||
|
|||
"github.com/lxn/walk" |
|||
. "github.com/lxn/walk/declarative" |
|||
) |
|||
|
|||
type MyMainWindow struct { |
|||
*walk.MainWindow |
|||
edit *walk.TextEdit |
|||
} |
|||
|
|||
func main() { |
|||
mw := &MyMainWindow{} |
|||
if err := (MainWindow{ |
|||
AssignTo: &mw.MainWindow, |
|||
MinSize: Size{400, 300}, |
|||
Size: Size{600, 400}, |
|||
MenuItems: []MenuItem{ |
|||
Menu{ |
|||
Text: "文件", |
|||
Items: []MenuItem{ |
|||
Action{ |
|||
Text: "打开文件", |
|||
Shortcut: Shortcut{ //定义快捷键后会有响应提示显示
|
|||
Modifiers: walk.ModControl, |
|||
Key: walk.KeyO, |
|||
}, |
|||
OnTriggered: mw.openFileActionTriggered, //点击动作触发响应函数
|
|||
}, |
|||
Action{ |
|||
Text: "另存为", |
|||
Shortcut: Shortcut{ |
|||
Modifiers: walk.ModControl | walk.ModShift, |
|||
Key: walk.KeyS, |
|||
}, |
|||
OnTriggered: mw.saveFileActionTriggered, |
|||
}, |
|||
Action{ |
|||
Text: "退出", |
|||
OnTriggered: func() { |
|||
mw.Close() |
|||
}, |
|||
}, |
|||
}, |
|||
}, |
|||
Menu{ |
|||
Text: "帮助", |
|||
Items: []MenuItem{ |
|||
Action{ |
|||
Text: "关于", |
|||
OnTriggered: func() { |
|||
walk.MsgBox(mw, "关于", "这是一个菜单和工具栏的实例", |
|||
walk.MsgBoxIconInformation|walk.MsgBoxDefButton1) |
|||
}, |
|||
}, |
|||
}, |
|||
}, |
|||
}, |
|||
ToolBar: ToolBar{ //工具栏
|
|||
ButtonStyle: ToolBarButtonTextOnly, |
|||
Items: []MenuItem{ |
|||
Menu{ |
|||
Text: "New", |
|||
Items: []MenuItem{ |
|||
Action{ |
|||
Text: "A", |
|||
OnTriggered: mw.newAction_Triggered, |
|||
}, |
|||
Action{ |
|||
Text: "B", |
|||
OnTriggered: mw.newAction_Triggered, |
|||
}, |
|||
}, |
|||
OnTriggered: mw.newAction_Triggered, //在菜单中不可如此定义,会无响应
|
|||
}, |
|||
Separator{}, //分隔符
|
|||
Action{ |
|||
Text: "View", |
|||
OnTriggered: mw.changeViewAction_Triggered, |
|||
}, |
|||
}, |
|||
}, |
|||
Layout: VBox{}, |
|||
Children: []Widget{ |
|||
TextEdit{ |
|||
AssignTo: &mw.edit, |
|||
}, |
|||
}, |
|||
OnDropFiles: mw.dropFiles, //放置文件事件响应函数
|
|||
}).Create(); err != nil { |
|||
fmt.Fprintln(os.Stderr, err) |
|||
return |
|||
} |
|||
|
|||
mw.Run() |
|||
} |
|||
|
|||
func (mw *MyMainWindow) openFileActionTriggered() { |
|||
dlg := new(walk.FileDialog) |
|||
dlg.Title = "打开文件" |
|||
dlg.Filter = "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*" |
|||
|
|||
if ok, err := dlg.ShowOpen(mw); err != nil { |
|||
fmt.Fprintln(os.Stderr, "错误:打开文件时\r\n") |
|||
return |
|||
} else if !ok { |
|||
fmt.Fprintln(os.Stderr, "用户取消\r\n") |
|||
return |
|||
} |
|||
|
|||
s := fmt.Sprintf("选择了:%s\r\n", dlg.FilePath) |
|||
mw.edit.SetText(s) |
|||
} |
|||
|
|||
func (mw *MyMainWindow) saveFileActionTriggered() { |
|||
dlg := new(walk.FileDialog) |
|||
dlg.Title = "另存为" |
|||
|
|||
if ok, err := dlg.ShowSave(mw); err != nil { |
|||
fmt.Fprintln(os.Stderr, err) |
|||
return |
|||
} else if !ok { |
|||
fmt.Fprintln(os.Stderr, "取消") |
|||
return |
|||
} |
|||
|
|||
data := mw.edit.Text() |
|||
filename := dlg.FilePath |
|||
f, err := os.Open(filename) |
|||
if err != nil { |
|||
f, _ = os.Create(filename) |
|||
} else { |
|||
f.Close() |
|||
f, err = os.OpenFile(filename, os.O_WRONLY, 0x666) |
|||
} |
|||
if len(data) == 0 { |
|||
f.Close() |
|||
return |
|||
} |
|||
io.Copy(f, strings.NewReader(data)) |
|||
f.Close() |
|||
} |
|||
|
|||
func (mw *MyMainWindow) newAction_Triggered() { |
|||
walk.MsgBox(mw, "New", "Newing something up... or not.", walk.MsgBoxIconInformation) |
|||
} |
|||
|
|||
func (mw *MyMainWindow) changeViewAction_Triggered() { |
|||
walk.MsgBox(mw, "Change View", "By now you may have guessed it. Nothing changed.", walk.MsgBoxIconInformation) |
|||
} |
|||
|
|||
func (mw *MyMainWindow) dropFiles(files []string) { |
|||
mw.edit.SetText("") |
|||
for _, v := range files { |
|||
mw.edit.AppendText(v + "\r\n") |
|||
} |
|||
} |
@ -0,0 +1,95 @@ |
|||
// Copyright 2016 The Walk Authors. All rights reserved.
|
|||
// Use of this source code is governed by a BSD-style
|
|||
// license that can be found in the LICENSE file.
|
|||
|
|||
package main |
|||
|
|||
import ( |
|||
"log" |
|||
|
|||
"github.com/lxn/walk" |
|||
. "github.com/lxn/walk/declarative" |
|||
) |
|||
|
|||
func main() { |
|||
var slv, slh *walk.Slider |
|||
var maxEdit, minEdit, valueEdit *walk.NumberEdit |
|||
|
|||
data := struct{ Min, Max, Value int }{0, 100, 30} |
|||
|
|||
MainWindow{ |
|||
Title: "Walk Slider Example", |
|||
MinSize: Size{320, 240}, |
|||
Layout: HBox{}, |
|||
Children: []Widget{ |
|||
Slider{ |
|||
AssignTo: &slv, |
|||
MinValue: data.Min, |
|||
MaxValue: data.Max, |
|||
Value: data.Value, |
|||
Orientation: Vertical, |
|||
OnValueChanged: func() { |
|||
data.Value = slv.Value() |
|||
valueEdit.SetValue(float64(data.Value)) |
|||
|
|||
}, |
|||
}, |
|||
Composite{ |
|||
Layout: Grid{Columns: 3}, |
|||
StretchFactor: 4, |
|||
Children: []Widget{ |
|||
Label{Text: "Min value"}, |
|||
Label{Text: "Value"}, |
|||
Label{Text: "Max value"}, |
|||
NumberEdit{ |
|||
AssignTo: &minEdit, |
|||
Value: float64(data.Min), |
|||
OnValueChanged: func() { |
|||
data.Min = int(minEdit.Value()) |
|||
slh.SetRange(data.Min, data.Max) |
|||
slv.SetRange(data.Min, data.Max) |
|||
}, |
|||
}, |
|||
NumberEdit{ |
|||
AssignTo: &valueEdit, |
|||
Value: float64(data.Value), |
|||
OnValueChanged: func() { |
|||
data.Value = int(valueEdit.Value()) |
|||
slh.SetValue(data.Value) |
|||
slv.SetValue(data.Value) |
|||
}, |
|||
}, |
|||
NumberEdit{ |
|||
AssignTo: &maxEdit, |
|||
Value: float64(data.Max), |
|||
OnValueChanged: func() { |
|||
data.Max = int(maxEdit.Value()) |
|||
slh.SetRange(data.Min, data.Max) |
|||
slv.SetRange(data.Min, data.Max) |
|||
}, |
|||
}, |
|||
Slider{ |
|||
ColumnSpan: 3, |
|||
AssignTo: &slh, |
|||
MinValue: data.Min, |
|||
MaxValue: data.Max, |
|||
Value: data.Value, |
|||
OnValueChanged: func() { |
|||
data.Value = slh.Value() |
|||
valueEdit.SetValue(float64(data.Value)) |
|||
}, |
|||
}, |
|||
VSpacer{}, |
|||
PushButton{ |
|||
ColumnSpan: 3, |
|||
Text: "Print state", |
|||
OnClicked: func() { |
|||
log.Printf("H: < %d | %d | %d >\n", slh.MinValue(), slh.Value(), slh.MaxValue()) |
|||
log.Printf("V: < %d | %d | %d >\n", slv.MinValue(), slv.Value(), slv.MaxValue()) |
|||
}, |
|||
}, |
|||
}, |
|||
}, |
|||
}, |
|||
}.Run() |
|||
} |
@ -0,0 +1,49 @@ |
|||
// Copyright 2010 The Walk Authors. All rights reserved.
|
|||
// Use of this source code is governed by a BSD-style
|
|||
// license that can be found in the LICENSE file.
|
|||
|
|||
package main |
|||
|
|||
import ( |
|||
"strings" |
|||
|
|||
"github.com/lxn/walk" |
|||
. "github.com/lxn/walk/declarative" |
|||
) |
|||
|
|||
func main() { |
|||
var le *walk.LineEdit |
|||
var wv *walk.WebView |
|||
|
|||
MainWindow{ |
|||
Icon: Bind("'../img/' + icon(wv.URL) + '.ico'"), |
|||
Title: "Walk WebView Example'", |
|||
MinSize: Size{800, 600}, |
|||
Layout: VBox{MarginsZero: true}, |
|||
Children: []Widget{ |
|||
LineEdit{ |
|||
AssignTo: &le, |
|||
Text: Bind("wv.URL"), |
|||
OnKeyDown: func(key walk.Key) { |
|||
if key == walk.KeyReturn { |
|||
wv.SetURL(le.Text()) |
|||
} |
|||
}, |
|||
}, |
|||
WebView{ |
|||
AssignTo: &wv, |
|||
Name: "wv", |
|||
URL: "https://github.com/lxn/walk", |
|||
}, |
|||
}, |
|||
Functions: map[string]func(args ...interface{}) (interface{}, error){ |
|||
"icon": func(args ...interface{}) (interface{}, error) { |
|||
if strings.HasPrefix(args[0].(string), "https") { |
|||
return "check", nil |
|||
} |
|||
|
|||
return "stop", nil |
|||
}, |
|||
}, |
|||
}.Run() |
|||
} |
@ -0,0 +1,239 @@ |
|||
// Copyright 2011 The Walk Authors. All rights reserved.
|
|||
// Use of this source code is governed by a BSD-style
|
|||
// license that can be found in the LICENSE file.
|
|||
|
|||
package main |
|||
|
|||
import ( |
|||
"fmt" |
|||
"math/rand" |
|||
"sort" |
|||
"strings" |
|||
"time" |
|||
) |
|||
|
|||
import ( |
|||
"github.com/lxn/walk" |
|||
. "github.com/lxn/walk/declarative" |
|||
) |
|||
|
|||
type Foo struct { |
|||
Index int |
|||
Bar string |
|||
Baz float64 |
|||
Quux time.Time |
|||
checked bool |
|||
} |
|||
|
|||
type FooModel struct { |
|||
walk.TableModelBase |
|||
walk.SorterBase |
|||
sortColumn int |
|||
sortOrder walk.SortOrder |
|||
items []*Foo |
|||
} |
|||
|
|||
func NewFooModel() *FooModel { |
|||
m := new(FooModel) |
|||
m.ResetRows() |
|||
return m |
|||
} |
|||
|
|||
// Called by the TableView from SetModel and every time the model publishes a
|
|||
// RowsReset event.
|
|||
func (m *FooModel) RowCount() int { |
|||
return len(m.items) |
|||
} |
|||
|
|||
// Called by the TableView when it needs the text to display for a given cell.
|
|||
func (m *FooModel) Value(row, col int) interface{} { |
|||
item := m.items[row] |
|||
|
|||
switch col { |
|||
case 0: |
|||
return item.Index |
|||
|
|||
case 1: |
|||
return item.Bar |
|||
|
|||
case 2: |
|||
return item.Baz |
|||
|
|||
case 3: |
|||
return item.Quux |
|||
} |
|||
|
|||
panic("unexpected col") |
|||
} |
|||
|
|||
// Called by the TableView to retrieve if a given row is checked.
|
|||
func (m *FooModel) Checked(row int) bool { |
|||
return m.items[row].checked |
|||
} |
|||
|
|||
// Called by the TableView when the user toggled the check box of a given row.
|
|||
func (m *FooModel) SetChecked(row int, checked bool) error { |
|||
m.items[row].checked = checked |
|||
|
|||
return nil |
|||
} |
|||
|
|||
// Called by the TableView to sort the model.
|
|||
func (m *FooModel) Sort(col int, order walk.SortOrder) error { |
|||
m.sortColumn, m.sortOrder = col, order |
|||
|
|||
sort.SliceStable(m.items, func(i, j int) bool { |
|||
a, b := m.items[i], m.items[j] |
|||
|
|||
c := func(ls bool) bool { |
|||
if m.sortOrder == walk.SortAscending { |
|||
return ls |
|||
} |
|||
|
|||
return !ls |
|||
} |
|||
|
|||
switch m.sortColumn { |
|||
case 0: |
|||
return c(a.Index < b.Index) |
|||
|
|||
case 1: |
|||
return c(a.Bar < b.Bar) |
|||
|
|||
case 2: |
|||
return c(a.Baz < b.Baz) |
|||
|
|||
case 3: |
|||
return c(a.Quux.Before(b.Quux)) |
|||
} |
|||
|
|||
panic("unreachable") |
|||
}) |
|||
|
|||
return m.SorterBase.Sort(col, order) |
|||
} |
|||
|
|||
func (m *FooModel) ResetRows() { |
|||
// Create some random data.
|
|||
m.items = make([]*Foo, rand.Intn(50000)) |
|||
|
|||
now := time.Now() |
|||
|
|||
for i := range m.items { |
|||
m.items[i] = &Foo{ |
|||
Index: i, |
|||
Bar: strings.Repeat("*", rand.Intn(5)+1), |
|||
Baz: rand.Float64() * 1000, |
|||
Quux: time.Unix(rand.Int63n(now.Unix()), 0), |
|||
} |
|||
} |
|||
|
|||
// Notify TableView and other interested parties about the reset.
|
|||
m.PublishRowsReset() |
|||
|
|||
m.Sort(m.sortColumn, m.sortOrder) |
|||
} |
|||
|
|||
func main() { |
|||
rand.Seed(time.Now().UnixNano()) |
|||
|
|||
boldFont, _ := walk.NewFont("Segoe UI", 9, walk.FontBold) |
|||
goodIcon, _ := walk.Resources.Icon("../img/check.ico") |
|||
badIcon, _ := walk.Resources.Icon("../img/stop.ico") |
|||
|
|||
barBitmap, err := walk.NewBitmap(walk.Size{100, 1}) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
defer barBitmap.Dispose() |
|||
|
|||
canvas, err := walk.NewCanvasFromImage(barBitmap) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
defer barBitmap.Dispose() |
|||
|
|||
canvas.GradientFillRectangle(walk.RGB(255, 0, 0), walk.RGB(0, 255, 0), walk.Horizontal, walk.Rectangle{0, 0, 100, 1}) |
|||
|
|||
canvas.Dispose() |
|||
|
|||
model := NewFooModel() |
|||
|
|||
var tv *walk.TableView |
|||
|
|||
MainWindow{ |
|||
Title: "Walk TableView Example", |
|||
Size: Size{800, 600}, |
|||
Layout: VBox{MarginsZero: true}, |
|||
Children: []Widget{ |
|||
PushButton{ |
|||
Text: "Reset Rows", |
|||
OnClicked: model.ResetRows, |
|||
}, |
|||
PushButton{ |
|||
Text: "Select first 5 even Rows", |
|||
OnClicked: func() { |
|||
tv.SetSelectedIndexes([]int{0, 2, 4, 6, 8}) |
|||
}, |
|||
}, |
|||
TableView{ |
|||
AssignTo: &tv, |
|||
AlternatingRowBG: true, |
|||
CheckBoxes: true, |
|||
ColumnsOrderable: true, |
|||
MultiSelection: true, |
|||
Columns: []TableViewColumn{ |
|||
{Title: "#"}, |
|||
{Title: "Bar"}, |
|||
{Title: "Baz", Alignment: AlignFar}, |
|||
{Title: "Quux", Format: "2006-01-02 15:04:05", Width: 150}, |
|||
}, |
|||
StyleCell: func(style *walk.CellStyle) { |
|||
item := model.items[style.Row()] |
|||
|
|||
if item.checked { |
|||
if style.Row()%2 == 0 { |
|||
style.BackgroundColor = walk.RGB(159, 215, 255) |
|||
} else { |
|||
style.BackgroundColor = walk.RGB(143, 199, 239) |
|||
} |
|||
} |
|||
|
|||
switch style.Col() { |
|||
case 1: |
|||
if canvas := style.Canvas(); canvas != nil { |
|||
bounds := style.Bounds() |
|||
bounds.X += 2 |
|||
bounds.Y += 2 |
|||
bounds.Width = int((float64(bounds.Width) - 4) / 5 * float64(len(item.Bar))) |
|||
bounds.Height -= 4 |
|||
canvas.DrawBitmapPartWithOpacity(barBitmap, bounds, walk.Rectangle{0, 0, 100 / 5 * len(item.Bar), 1}, 127) |
|||
|
|||
bounds.X += 4 |
|||
bounds.Y += 2 |
|||
canvas.DrawText(item.Bar, tv.Font(), 0, bounds, walk.TextLeft) |
|||
} |
|||
|
|||
case 2: |
|||
if item.Baz >= 900.0 { |
|||
style.TextColor = walk.RGB(0, 191, 0) |
|||
style.Image = goodIcon |
|||
} else if item.Baz < 100.0 { |
|||
style.TextColor = walk.RGB(255, 0, 0) |
|||
style.Image = badIcon |
|||
} |
|||
|
|||
case 3: |
|||
if item.Quux.After(time.Now().Add(-365 * 24 * time.Hour)) { |
|||
style.Font = boldFont |
|||
} |
|||
} |
|||
}, |
|||
Model: model, |
|||
OnSelectedIndexesChanged: func() { |
|||
fmt.Printf("SelectedIndexes: %v\n", tv.SelectedIndexes()) |
|||
}, |
|||
}, |
|||
}, |
|||
}.Run() |
|||
} |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in new issue