func osOpenWindow(window *Window, url string, styleFlags int) { fmt.Println("osOpenWindow: ", window, url, styleFlags) var dia *walk.Dialog var le *walk.LineEdit var wv *walk.WebView windowStore[window.handle] = dia Dialog{ AssignTo: &dia, Title: "Window Title", 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: url, }, }, }.Run(mainWindow) }
func main() { var le *walk.LineEdit var wv *walk.WebView MainWindow{ 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: "http://golang.org", }, }, }.Run() }
func ParseNumber(textbox *walk.LineEdit) float64 { number, err := strconv.ParseFloat(textbox.Text(), 64) widgets := textbox.Parent().Children() index := widgets.Index(textbox) label := widgets.At(index + 1).(*walk.Label) if err != nil { label.SetText("需要填入数字") } else { label.SetText("") } return number }
func main() { var ( te *walk.TextEdit le *walk.LineEdit ) MainWindow{ Title: _WIN_TITLE, MinSize: Size{300, 400}, Layout: VBox{}, Children: []Widget{ Label{ Text: _WIN_LABEL_HOST, }, LineEdit{ AssignTo: &le, Text: GetHttpHost(), }, Label{ Text: _WIN_LABEL_LINK, }, TextEdit{ AssignTo: &te, }, Composite{ Layout: HBox{}, Children: []Widget{ PushButton{ Text: _WIN_GEN_BUTTON, OnClicked: func() { URL, err := url.Parse(te.Text()) if err != nil { return } genURL := generateURL(URL, le.Text()) if genURL != nil { te.SetText(genURL.String()) } }, }, PushButton{ Text: _WIN_COPY_BUTTON, OnClicked: func() { walk.Clipboard().SetText(te.Text()) }, }, }, }, }, }.Run() }
func main() { var le *walk.LineEdit var wv *walk.WebView MainWindow{ Title: "Walk WebView Example", MinSize: Size{800, 600}, Layout: VBox{}, Children: []Widget{ LineEdit{ AssignTo: &le, Text: Bind("wv.URL"), OnReturnPressed: func() { wv.SetURL(le.Text()) }, }, WebView{ AssignTo: &wv, Name: "wv", URL: "http://golang.org", }, }, }.Run() }
func main() { var ( msgbox *walk.TextEdit inputUN *walk.LineEdit //input username inputPW *walk.LineEdit //input password myPB *walk.PushButton ) MainWindow{ Title: "soramail", MinSize: Size{640, 480}, Layout: VBox{}, Children: []Widget{ TextEdit{ AssignTo: &msgbox, Text: "Hello, World", ReadOnly: true, }, HSplitter{ MaxSize: Size{640, 20}, Children: []Widget{ LineEdit{ AssignTo: &inputUN, Text: "username", }, LineEdit{ AssignTo: &inputPW, Text: "password", }, PushButton{ AssignTo: &myPB, Text: "Push", OnClicked: func() { msgbox.AppendText("\r\nHello," + inputUN.Text() + ".\r\nYour password is " + inputPW.Text()) }, }, }, }, }, }.Run() }
func (mw *MyMainWindow) showDialogAction_Triggered() { dlg := new(MyDialog) var acceptPB *walk.PushButton var le1, le2 *walk.LineEdit widgets := []Widget{ Label{Row: 0, Column: 0, Text: "A LineEdit:"}, LineEdit{Row: 0, Column: 1, AssignTo: &le1, OnTextChanged: func() { le2.SetText(le1.Text()) }}, ToolButton{Row: 0, Column: 2, Text: "..."}, Label{Row: 1, Column: 0, Text: "Another LineEdit:"}, LineEdit{Row: 1, Column: 1, AssignTo: &le2}, Label{Row: 2, Column: 0, Text: "A ComboBox:"}, ComboBox{Row: 2, Column: 1}, VSpacer{Row: 3, Column: 0, Size: 10}, Label{Row: 4, Column: 0, ColumnSpan: 2, Text: "A TextEdit:"}, TextEdit{Row: 5, Column: 0, ColumnSpan: 2}, } dd := &DialogDecl{ Title: "My Dialog", Owner: mw, Dialog: &dlg.Dialog, AcceptPB: &acceptPB, Widgets: widgets, MinSize: Size{400, 300}, } if err := dd.Create(); err != nil { log.Fatal(err) } acceptPB.Clicked().Attach(func() { dlg.Accept() }) dlg.Run() }
func main() { var aTE, bTE, cTE, dTE *walk.LineEdit var outTE *walk.TextEdit var mw *walk.MainWindow defer func() { if e := recover(); e != nil { walk.MsgBox(mw, "Error", fmt.Sprintf("%v", e), walk.MsgBoxIconInformation) } }() MainWindow{ AssignTo: &mw, Title: "24 Game", MinSize: Size{600, 400}, Layout: VBox{}, Children: []Widget{ Composite{ Layout: HBox{}, Children: []Widget{ Label{Text: "a"}, LineEdit{AssignTo: &aTE}, Label{Text: "b"}, LineEdit{AssignTo: &bTE}, Label{Text: "c"}, LineEdit{AssignTo: &cTE}, Label{Text: "d"}, LineEdit{AssignTo: &dTE}, PushButton{ Text: "Go", OnClicked: func() { rand.Seed(time.Now().Unix()) aTE.SetText(fmt.Sprint(rand.Intn(13) + 1)) bTE.SetText(fmt.Sprint(rand.Intn(13) + 1)) cTE.SetText(fmt.Sprint(rand.Intn(13) + 1)) dTE.SetText(fmt.Sprint(rand.Intn(13) + 1)) }, }, }, }, TextEdit{AssignTo: &outTE, ReadOnly: true}, PushButton{ Text: "Compute", OnClicked: func() { a, err := strconv.ParseInt(aTE.Text(), 10, 64) b, err := strconv.ParseInt(bTE.Text(), 10, 64) c, err := strconv.ParseInt(cTE.Text(), 10, 64) d, err := strconv.ParseInt(dTE.Text(), 10, 64) if err != nil { walk.MsgBox(mw, "Error", err.Error(), walk.MsgBoxIconInformation) } outTE.SetText("") for solution := range findSolution(a, b, c, d) { outTE.AppendText(fmt.Sprintf("%s = 24\r\n", solution)) } if outTE.Text() == "" { outTE.SetText("No solution.") } }, }, }, }.Run() }
func main() { fout, _ := os.Create("dialer.log") defer fout.Close() bo := bufio.NewWriter(fout) defer bo.Flush() util.INFO.SetOutput(bo) util.ERROR.SetOutput(bo) bin, err := ioutil.ReadFile("config.json") if err == nil { json.Unmarshal(bin, config) } else { util.ERROR.Log(err) err = nil } var usr, pwd *walk.LineEdit var raddr, rusr, rpwd *walk.LineEdit var lb, rb *walk.PushButton var mode *walk.ComboBox var mw *walk.MainWindow var db *walk.DataBinder var laddr, lusr, lpwd *walk.Splitter go func() { for mw == nil { runtime.Gosched() } ic, err := walk.NewIconFromResourceId(6) if err == nil { // func onLoad() { db.SetAutoSubmit(true) mw.SetIcon(ic) switch config.RouterType { case "hiwifi": laddr.SetVisible(true) lusr.SetVisible(false) lpwd.SetVisible(true) case "openwrt": laddr.SetVisible(true) lusr.SetVisible(true) lpwd.SetVisible(true) case "asus": laddr.SetVisible(true) lusr.SetVisible(true) lpwd.SetVisible(true) default: laddr.SetVisible(false) lusr.SetVisible(false) lpwd.SetVisible(false) } mw.SetSize(walk.Size{0, 0}) // } } }() MainWindow{ AssignTo: &mw, Title: TITLE, MinSize: Size{340, 0}, Layout: VBox{}, DataBinder: DataBinder{ AssignTo: &db, DataSource: config, }, Children: []Widget{ HSplitter{ Children: []Widget{ Label{Text: "用户名", MaxSize: Size{60, 20}}, LineEdit{Text: Bind("Username"), AssignTo: &usr, MaxSize: Size{0, 20}}, }, MaxSize: Size{0, 20}, }, HSplitter{ Children: []Widget{ Label{Text: "密码", MaxSize: Size{60, 20}}, LineEdit{Text: Bind("Password"), AssignTo: &pwd, MaxSize: Size{0, 20}, PasswordMode: true, OnMouseDown: func(x, y int, button walk.MouseButton) { pwd.SetPasswordMode(false) }, OnMouseUp: func(x, y int, button walk.MouseButton) { pwd.SetPasswordMode(true) }, }, }, MaxSize: Size{0, 20}, }, HSplitter{ Children: []Widget{ Label{Text: "模式", MaxSize: Size{60, 20}}, ComboBox{AssignTo: &mode, Editable: true, Value: Bind("RouterType"), Model: []string{"local", "10.0.x.x(手动填写)", "openwrt", "hiwifi", "asus"}, MaxSize: Size{0, 20}, OnCurrentIndexChanged: func() { switch mode.CurrentIndex() { case 2: //"openwrt": laddr.SetVisible(true) lusr.SetVisible(true) lpwd.SetVisible(true) case 3: //"hiwifi": config.RouterAddr = "192.168.199.1" laddr.SetVisible(true) lusr.SetVisible(false) lpwd.SetVisible(true) case 4: //"asus": laddr.SetVisible(true) lusr.SetVisible(true) lpwd.SetVisible(true) default: laddr.SetVisible(false) lusr.SetVisible(false) lpwd.SetVisible(false) } mw.SetSize(walk.Size{0, 0}) }, }, }, MaxSize: Size{0, 20}, }, HSplitter{ AssignTo: &laddr, Children: []Widget{ Label{Text: "路由地址", MaxSize: Size{60, 20}}, LineEdit{Text: Bind("RouterAddr"), AssignTo: &raddr, MaxSize: Size{0, 20}}, }, MaxSize: Size{0, 20}, }, HSplitter{ AssignTo: &lusr, Children: []Widget{ Label{Text: "路由用户名", MaxSize: Size{60, 20}}, LineEdit{Text: Bind("RouterUser"), AssignTo: &rusr, MaxSize: Size{0, 20}}, }, MaxSize: Size{0, 20}, }, HSplitter{ AssignTo: &lpwd, Children: []Widget{ Label{Text: "路由密码", MaxSize: Size{60, 20}}, LineEdit{Text: Bind("RouterPwd"), AssignTo: &rpwd, MaxSize: Size{0, 20}, PasswordMode: true, OnMouseDown: func(x, y int, button walk.MouseButton) { rpwd.SetPasswordMode(false) }, OnMouseUp: func(x, y int, button walk.MouseButton) { rpwd.SetPasswordMode(true) }, }, }, MaxSize: Size{0, 20}, }, HSplitter{ Children: []Widget{ PushButton{ AssignTo: &lb, Text: "开始连接", OnClicked: func() { if mode.Text() == "10.0.x.x(手动填写)" { walk.MsgBox(mw, "请填写IP", "手动填写需要自己获取IP 你可在路由器中自己查找 本地拨号请用local", walk.MsgBoxOK) return } lb.SetText("连接中...") lb.SetEnabled(false) rb.SetEnabled(false) go func() { d := netdialer.NewDialer(usr.Text(), pwd.Text()) d.UserIP = selectMode(mode.Text()) if d.UserIP == "" { walk.MsgBox(mw, "连接失败", "请检查设置", walk.MsgBoxOK) d = nil return } d.ConnectDirect() mw.SetTitle(TITLE + " [" + d.UserIP + "]") d = nil lb.SetEnabled(true) rb.SetEnabled(true) lb.SetText("开始连接") if err == nil { walk.MsgBox(mw, "连接成功", "感谢使用", walk.MsgBoxOK) util.INFO.Log("连接成功: 感谢使用") } else { walk.MsgBox(mw, "连接失败", err.Error(), walk.MsgBoxOK) util.INFO.Log("连接失败: ", err.Error()) } }() }, }, PushButton{ AssignTo: &rb, Text: "断开连接", OnClicked: func() { if mode.Text() == "10.0.x.x(手动填写)" { walk.MsgBox(mw, "请填写IP", "手动填写需要自己获取IP 你可在路由器中自己查找", walk.MsgBoxOK) return } rb.SetText("断开中...") lb.SetEnabled(false) rb.SetEnabled(false) go func() { d := netdialer.NewDialer(usr.Text(), pwd.Text()) d.UserIP = selectMode(mode.Text()) if d.UserIP == "" { walk.MsgBox(mw, "连接失败", "请检查设置", walk.MsgBoxOK) util.INFO.Log("连接失败: 请检查设置") d = nil return } err := d.DisconnectDirect() mw.SetTitle(TITLE + " [" + d.UserIP + "]") d = nil lb.SetEnabled(true) rb.SetEnabled(true) rb.SetText("断开连接") if err == nil { walk.MsgBox(mw, "断开成功", "感谢使用", walk.MsgBoxOK) util.INFO.Log("断开成功: 感谢使用") } else { walk.MsgBox(mw, "断开失败", err.Error(), walk.MsgBoxOK) util.INFO.Log("断开失败: ", err.Error()) } }() }, }, }, MaxSize: Size{0, 20}, }, }, }.Run() saveConfig(config) bo.Flush() }
/** *添加版本的方法 */ func CreateVersion_Triggered(owner walk.Form, model *xorm.VersionModel) { var dlg *walk.Dialog var db *walk.DataBinder var dph *walk.LineEdit var ep walk.ErrorPresenter var version = new(xorm.Version) var acceptPB, cancelPB *walk.PushButton var dialog = Dialog{} dialog.AssignTo = &dlg dialog.Title = "创建版本" dialog.DataBinder = DataBinder{ AssignTo: &db, DataSource: version, ErrorPresenter: ErrorPresenterRef{&ep}, } dialog.MinSize = Size{300, 200} dialog.Layout = VBox{} dialog.DefaultButton = &acceptPB dialog.CancelButton = &cancelPB dirPath := LineEdit{ AssignTo: &dph, Text: Bind("Path"), ReadOnly: true, } childrens := []Widget{ Composite{ Layout: Grid{Columns: 5}, Children: []Widget{ Label{ Text: "工程:", MinSize: Size{42, 0}, }, ComboBox{ MinSize: Size{108, 0}, Value: Bind("ProjectName", SelRequired{}), BindingMember: "Key", DisplayMember: "Name", Model: xorm.FindAllProjDataCombox(), }, dirPath, PushButton{ Text: "选择版本", OnClicked: func() { filDlg := new(walk.FileDialog) filDlg.ShowBrowseFolder(owner) dph.SetText(filDlg.FilePath) }, }, }, }, Composite{ Layout: Grid{Columns: 2}, Children: []Widget{ Label{ Text: "名称:", }, LineEdit{ Text: Bind("Name"), MaxLength: 10, }, Label{ Text: "创建者:", }, LineEdit{ Text: Bind("CreateUser"), MaxLength: 10, }, Label{ Text: "描述:", }, TextEdit{ Text: Bind("Desc"), MinSize: Size{300, 50}, }, LineErrorPresenter{ AssignTo: &ep, ColumnSpan: 2, }, }, }, Composite{ Layout: HBox{}, Children: []Widget{ HSpacer{}, PushButton{ AssignTo: &acceptPB, Text: "保存", OnClicked: func() { if err := db.Submit(); err != nil { log.Print(err) return } xorm.SaveVersionByParam(version.Name, version.CreateUser, version.Desc) model.ResetRows() dlg.Accept() }, }, PushButton{ AssignTo: &cancelPB, Text: "取消", OnClicked: func() { dlg.Cancel() }, }, }, }, } dialog.Children = childrens dialog.Run(owner) }
func main() { mw := new(MyMainWindow) var openButton *walk.PushButton var hostEdit, destEdit, portEdit *walk.LineEdit var logTextEdit *walk.TextEdit closeMessage := make(chan int) MainWindow{ AssignTo: &mw.MainWindow, Title: "SCREAMO", MinSize: Size{600, 400}, Layout: VBox{}, Children: []Widget{ Composite{ Layout: Grid{}, Children: []Widget{ Label{ Row: 0, Column: 0, Text: "JmsHost:", }, LineEdit{ AssignTo: &hostEdit, Row: 0, Column: 1, Text: "192.168.1.105", }, Label{ Row: 1, Column: 0, Text: "JmsDest:", }, LineEdit{ AssignTo: &destEdit, Row: 1, Column: 1, Text: "/topic/IDC.QuoteExchange.bond2app", }, Label{ Row: 2, Column: 0, Text: "JmsPort:", }, LineEdit{ AssignTo: &portEdit, Row: 2, Column: 1, Text: "61612", }, }, }, Composite{ Layout: HBox{}, Children: []Widget{ PushButton{ AssignTo: &openButton, Text: "Open", OnClicked: func() { if openButton.Text() == "Open" { go openstomp(hostEdit.Text(), destEdit.Text(), portEdit.Text(), logTextEdit, closeMessage) openButton.SetText("Close") } else { go stopstomp(closeMessage) openButton.SetText("Open") } }, }, PushButton{ Text: "Clear", OnClicked: func() { logTextEdit.SetText("") }, }, }, }, TextEdit{ AssignTo: &logTextEdit, MinSize: Size{100, 50}, Text: "", ReadOnly: true, }, }, }.Run() }
func newToolBar() ToolBar { tb := ToolBar{ ButtonStyle: ToolBarButtonImageBeforeText, Items: []MenuItem{ Action{ AssignTo: &(context.addButton), Text: "新增", Image: "res/add.png", // Enabled: Bind("isSpecialMode && enabledCB.Checked"), OnTriggered: func() { var dlg *walk.Dialog var hostsNameEdit *walk.LineEdit Dialog{ AssignTo: &dlg, Title: "新增", MinSize: Size{300, 150}, Layout: VBox{}, Children: []Widget{ Composite{ Layout: Grid{Columns: 2}, Children: []Widget{ Label{ ColumnSpan: 2, Text: "Hosts名字:", }, LineEdit{ AssignTo: &hostsNameEdit, ColumnSpan: 2, // Text: Bind("PatienceField"), }, }, }, HSpacer{}, Composite{ Layout: HBox{}, Children: []Widget{ PushButton{ // AssignTo: &acceptPB, Text: "确定", OnClicked: func() { // if err := db.Submit(); err != nil { // log.Print(err) // return // } item := &model.HostConfigItem{Name: hostsNameEdit.Text(), Icon: common.IconMap[common.ICON_NEW]} conf.Config.HostConfigModel.Insert(item) context.treeView.SetCurrentItem(item) dlg.Accept() }, }, PushButton{ // AssignTo: &cancelPB, Text: "取消", OnClicked: func() { dlg.Cancel() }, }, }, }, }, }.Run(context.mw) }, }, //FIXME 去除刷新按钮是因为点击以后, 双击hosts不再生效 // Action{ // Text: "刷新", // Image: "res/refresh.png", // // Enabled: Bind("isSpecialMode && enabledCB.Checked"), // OnTriggered: func() { // conf.Load() // }, // }, // Action{ // Text: "修改", // Image: "res/pencil.png", // // Enabled: Bind("isSpecialMode && enabledCB.Checked"), // // OnTriggered: mw.specialAction_Triggered, // }, Action{ AssignTo: &(context.deleteButton), Text: "删除", Image: "res/delete.png", // Enabled: Bind("isSpecialMode && enabledCB.Checked"), OnTriggered: func() { if context.treeView.CurrentItem() == nil { walk.MsgBox(context.mw, "删除hosts", "请选择左边列表后再删除", walk.MsgBoxIconInformation) context.deleteButton.SetEnabled(false) return } current := context.treeView.CurrentItem().(*model.HostConfigItem) message := fmt.Sprintf("确定要删除hosts '%s'?", current.Text()) ret := walk.MsgBox(context.mw, "删除hosts", message, walk.MsgBoxYesNo) if ret == win.IDYES { if !conf.Config.HostConfigModel.Remove(current) { common.Error("Fail to remove current item: %v", current.Text()) // TODO notify user return } if context.treeView.Model().RootCount() > 0 { context.treeView.SetCurrentItem(context.treeView.Model().RootAt(0)) } file := "conf/hosts/" + current.Text() + ".hosts" if err := os.Remove(file); err != nil { common.Error("Fail to delete file: %s", file) // TODO notify user return } common.Info("Succeed to delete file: %s", file) } }, }, }, } return tb }
func main() { var le, le2 *walk.LineEdit var lb1, lb2 *walk.Label var ck1 *walk.CheckBox var mw *walk.MainWindow copytext, _ := walk.Clipboard().Text() updateIcon := func() { mainIcon, err := walk.NewIconFromResource("101") if err != nil { // do some work } mw.SetIcon(mainIcon) } if err := (MainWindow{ AssignTo: &mw, Title: "模板下载器", MinSize: Size{400, 100}, Layout: VBox{}, Children: []Widget{ CheckBox{ AssignTo: &ck1, Name: "cksnap", Text: "带截图抓取", Checked: false, }, Label{ AssignTo: &lb1, Text: "网址", }, LineEdit{ AssignTo: &le, Text: copytext, }, Label{ AssignTo: &lb2, Text: "保存目录", }, LineEdit{ AssignTo: &le2, Text: `D:\APMServ5.2.6\www\htdocs\down\tpls\`, }, PushButton{ Text: "开始抓取", OnClicked: func() { fmt.Println(ck1.Checked()) if ck1.Checked() { command := flag.String("cmd", "phantomjs", "Set the command.") patharr := strings.Split(le2.Text(), "\\") args := flag.String("args", "rasterize.js "+le.Text()+" "+le2.Text()+"\\"+patharr[len(patharr)-1]+".png", "Set the args. (separated by spaces)") var argArray []string if *args != "" { argArray = strings.Split(*args, " ") } else { argArray = make([]string, 0) } flag.Parse() cmd := exec.Command(*command, argArray...) buf, err := cmd.Output() if err != nil { fmt.Fprintf(os.Stderr, "The command failed to perform: %s (Command: %s, Arguments: %s)", err, *command, *args) return } fmt.Fprintf(os.Stdout, "Result: %s", buf) } getTemplate(le.Text(), le2.Text()) }, },
func main() { LoadData() chEnd = make(chan bool) var emails, body, msgbox *walk.TextEdit var user, password, host, subject *walk.LineEdit var startBtn *walk.PushButton MainWindow{ Title: "邮件群发器 By 一曲忧伤", MinSize: Size{800, 600}, Layout: HBox{}, Children: []Widget{ TextEdit{AssignTo: &emails, Text: SJ.Send, ToolTipText: "待发送邮件列表,每行一个"}, VSplitter{ Children: []Widget{ LineEdit{AssignTo: &user, Text: SJ.Name, CueBanner: "请输入邮箱用户名"}, LineEdit{AssignTo: &password, Text: SJ.Pwd, PasswordMode: true, CueBanner: "请输入邮箱登录密码"}, LineEdit{AssignTo: &host, Text: SJ.Host, CueBanner: "SMTP服务器:端口"}, LineEdit{AssignTo: &subject, Text: SJ.Subject, CueBanner: "请输入邮件主题……"}, TextEdit{AssignTo: &body, Text: SJ.Body, ToolTipText: "请输入邮件内容", ColumnSpan: 2}, TextEdit{AssignTo: &msgbox, ReadOnly: true}, PushButton{ AssignTo: &startBtn, Text: "开始群发", OnClicked: func() { SJ.Name = user.Text() SJ.Pwd = password.Text() SJ.Host = host.Text() SJ.Subject = subject.Text() SJ.Body = body.Text() SJ.Send = emails.Text() SaveData() if runing == false { runing = true startBtn.SetText("停止发送") go sendThread(msgbox, emails) } else { runing = false startBtn.SetText("开始群发") } }, }, }, }, }, }.Run() }
func main() { LoadData() chEnd = make(chan bool) var emails, body, msgbox *walk.TextEdit var user, password, host, subject *walk.LineEdit var db *walk.DataBinder var ep walk.ErrorPresenter var startBtn *walk.PushButton mw := new(MyMainWindow) mw.SetFixedSize(false) mw.SetMaximizeBox(false) MainWindow{ Title: "邮件群发器 By 一曲忧伤", MinSize: Size{300, 200}, AssignTo: &mw.MainWindow, DataBinder: DataBinder{ AssignTo: &db, DataSource: SJ, ErrorPresenter: ErrorPresenterRef{&ep}, }, ScreenCenter: true, Layout: HBox{}, Children: []Widget{ TextEdit{ AssignTo: &emails, Text: SJ.Send, ToolTipText: "待发送邮件列表,每行一个", }, VSplitter{ Children: []Widget{ LineEdit{ AssignTo: &user, Text: Bind(SJ.Name, Regexp{"^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"}), CueBanner: "请输入邮箱用户名", }, LineEdit{ AssignTo: &password, Text: SJ.Pwd, PasswordMode: true, CueBanner: "请输入邮箱登录密码", }, LineEdit{ AssignTo: &host, Text: Bind(SJ.Host, Regexp{"^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$"}), CueBanner: "SMTP服务器:端口", }, LineEdit{AssignTo: &subject, MaxLength: 10, Text: Bind(SJ.Subject, Regexp{"^([a-z0-9A-Z])+$"}), CueBanner: "请输入邮件主题……", }, TextEdit{AssignTo: &body, Text: Bind(SJ.Body, SelRequired{}), ToolTipText: "请输入邮件内容", ColumnSpan: 2, }, TextEdit{AssignTo: &msgbox, ReadOnly: true, }, LineErrorPresenter{ AssignTo: &ep, ColumnSpan: 2, ToolTipText: "测试", }, PushButton{ AssignTo: &startBtn, Text: "开始群发", OnClicked: func() { if err := db.Submit(); err == nil { SJ.Name = user.Text() SJ.Pwd = password.Text() SJ.Host = host.Text() SJ.Subject = subject.Text() SJ.Body = body.Text() SJ.Send = emails.Text() SaveData() if runing == false { runing = true startBtn.SetText("停止发送") go sendThread(msgbox, emails) } else { runing = false startBtn.SetText("开始群发") } } else { return } }, }, }, }, }, }.Run() }