教程三:go语言windows gui界面开发之walk 控件学习第二节之进度条

本文主要是介绍教程三:go语言windows gui界面开发之walk 控件学习第二节之进度条,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、任务栏进度条

1.1 实现思路

1.1.1 START(启动)按钮:启动进度条间隔100毫秒进度+1;
  • 第一步:新建Dialog窗口, 即创建*walk.Dialog类型变量dlg ;
  • 第二步:新建START按钮,即*walk.PushButton类型变量startBtn;
  • 第三步:dlg.ProgressIndicator().SetTotal(100)设置进度条总长;
  • 第四部:dlg.ProgressIndicator().SetCompleted(i)更新进度条当前进度,i就是更新后的值;
  • 第五步:第三步、第四部写在第二步创建的按钮点击事件中即可。
1.1.2 Paused(暂停)按钮:暂停进度条,并且进度条显示黄色;
  • 第一步:新建var stopChan chan struct{}通道,长度为1;
  • 第二步:Paused按钮事件时,向通道stopChan 写入数据stopChan <-struct{}{};
  • 第三步:此时START按钮拉起的进度条协程中向stopChan 写数据会阻塞,即实现暂停进度条;
1.1.3 Normal(恢复)按钮:恢复进度条进度,并且进度条恢复绿色
  • Normal按钮事件时,从通道stopChan中读取一次数据即可;
1.1.4 Error(出错)按钮:进度出错时使用,进度暂停,并且进度显示变红,
  • Error按钮事件时,向通道stopChan 写入数据stopChan <-struct{}{};
1.1.5 NoProgress(无进度状态)按钮:取消进度
  • 通知进度条进度接口退出,同时清除进度;
  • 实现:此处直接关闭通道stopChan ,在START任务重recover掉,比较暴力;
1.1.6 Indeterminate(不确定状态)按钮:取消进度
  • 该状态根据自己实际业务实现,此处略去;

1.2 效果图如下:

在这里插入图片描述
在这里插入图片描述

1.3代码如下

// main.go文件
package mainimport (. "log""os""runtime/debug""time""github.com/lxn/walk"
)var log *Logger
var stopChan chan struct{}func init() {log = CreateLogService()stopChan = make(chan struct{}, 1)
}// 创建日志服务
func CreateLogService() *Logger {file := "log.txt"logFile, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm) // 以读写方式打开文件,如果没有该名称文件则自动创建,以追加的方式写入文件if err != nil {return nil}logger := New(logFile, "[logInfo:]", LstdFlags|Lshortfile) // 将文件设置为loger作为输出return logger
}func main() {defer func() {err := recover()if err != nil {log.Printf("err:%s", err)log.Printf("stack:%s.", debug.Stack())}}()if _, err := RunMyDialog(nil); err != nil {log.Fatal(err)}
}type MyDialog struct {*walk.Dialogui myDialogUI
}func (dlg *MyDialog) setState(state walk.PIState) {if err := dlg.ProgressIndicator().SetState(state); err != nil {log.Print(err)}
}func RunMyDialog(owner walk.Form) (int, error) {dlg := new(MyDialog)if err := dlg.init(owner); err != nil {return 0, err}dlg.SetLayout(walk.NewHBoxLayout())dlg.ui.indeterminateBtn.Clicked().Attach(func() {log.Println("SetState indeterminate")dlg.setState(walk.PIIndeterminate)})dlg.ui.noProgressBtn.Clicked().Attach(func() {log.Println("SetState noprogress")close(stopChan)dlg.setState(walk.PINoProgress)})dlg.ui.normalBtn.Clicked().Attach(func() {log.Println("SetState normal")<-stopChandlg.setState(walk.PINormal)})dlg.ui.errBtn.Clicked().Attach(func() {log.Println("SetState error")stopChan <- struct{}{}dlg.setState(walk.PIError)})dlg.ui.pausedBtn.Clicked().Attach(func() {log.Println("SetState paused")stopChan <- struct{}{}dlg.setState(walk.PIPaused)})dlg.ui.startBtn.Clicked().Attach(func() {go func() {defer func() {recover()log.Println("start rent abort.")dlg.ProgressIndicator().SetCompleted(0)stopChan = make(chan struct{}, 1)}()dlg.ProgressIndicator().SetTotal(100)var i uint32for i = 0; i < 100; i++ {stopChan <- struct{}{}log.Println("SetProgress", i)time.Sleep(100 * time.Millisecond)if err := dlg.ProgressIndicator().SetCompleted(i); err != nil {log.Print(err)}<-stopChan}}()})return dlg.Run(), nil
}// dialog_ui.go
// THIS FILE WAS GENERATED BY A TOOL, DO NOT EDIT!package mainimport ("github.com/lxn/walk"
)type myDialogUI struct {noProgressBtn    *walk.PushButtonindeterminateBtn *walk.PushButtonnormalBtn        *walk.PushButtonerrBtn           *walk.PushButtonpausedBtn        *walk.PushButtonstartBtn         *walk.PushButton
}func (w *MyDialog) init(owner walk.Form) (err error) {if w.Dialog, err = walk.NewDialog(owner); err != nil {return err}succeeded := falsedefer func() {if !succeeded {w.Dispose()}}()var font *walk.Fontif font == nil {font = nil}w.SetName("Dialog")if err := w.SetClientSize(walk.Size{598, 300}); err != nil {return err}if err := w.SetTitle(`Dialog`); err != nil {return err}// noProgressBtnif w.ui.noProgressBtn, err = walk.NewPushButton(w); err != nil {return err}w.ui.noProgressBtn.SetName("noProgressBtn")if err := w.ui.noProgressBtn.SetBounds(walk.Rectangle{40, 60, 161, 23}); err != nil {return err}if err := w.ui.noProgressBtn.SetText(`NoProgress`); err != nil {return err}if err := w.ui.noProgressBtn.SetMinMaxSize(walk.Size{0, 0}, walk.Size{161, 16777215}); err != nil {return err}// indeterminateBtnif w.ui.indeterminateBtn, err = walk.NewPushButton(w); err != nil {return err}w.ui.indeterminateBtn.SetName("indeterminateBtn")if err := w.ui.indeterminateBtn.SetBounds(walk.Rectangle{40, 90, 161, 23}); err != nil {return err}if err := w.ui.indeterminateBtn.SetText(`Indeterminate`); err != nil {return err}if err := w.ui.indeterminateBtn.SetMinMaxSize(walk.Size{0, 0}, walk.Size{161, 16777215}); err != nil {return err}// normalBtnif w.ui.normalBtn, err = walk.NewPushButton(w); err != nil {return err}w.ui.normalBtn.SetName("normalBtn")if err := w.ui.normalBtn.SetBounds(walk.Rectangle{40, 120, 161, 23}); err != nil {return err}if err := w.ui.normalBtn.SetText(`Normal`); err != nil {return err}if err := w.ui.normalBtn.SetMinMaxSize(walk.Size{0, 0}, walk.Size{161, 16777215}); err != nil {return err}// errBtnif w.ui.errBtn, err = walk.NewPushButton(w); err != nil {return err}w.ui.errBtn.SetName("errBtn")if err := w.ui.errBtn.SetBounds(walk.Rectangle{40, 150, 161, 23}); err != nil {return err}if err := w.ui.errBtn.SetText(`Error`); err != nil {return err}// pausedBtnif w.ui.pausedBtn, err = walk.NewPushButton(w); err != nil {return err}w.ui.pausedBtn.SetName("pausedBtn")if err := w.ui.pausedBtn.SetBounds(walk.Rectangle{40, 180, 161, 23}); err != nil {return err}if err := w.ui.pausedBtn.SetText(`Paused`); err != nil {return err}// startBtnif w.ui.startBtn, err = walk.NewPushButton(w); err != nil {return err}w.ui.startBtn.SetName("startBtn")if err := w.ui.startBtn.SetBounds(walk.Rectangle{290, 180, 75, 23}); err != nil {return err}if err := w.ui.startBtn.SetText(`START`); err != nil {return err}// Tab ordersucceeded = truereturn nil
}

二、弹窗进度条

2.1 实现思路

  • 新建*walk.ProgressBar进度控件progressBar
  • 设置进度条范围progressBar.SetRange(0, 100),只有进度条的当前值为该范围才会有进度效果;
  • 设置进度条悬窗提示当前进度,progressBar.WidgetBase.SetToolTipText(strconv.FormatInt(n, 10));
  • 更新进度条当前值progressBar.SetValue(int(n));

2.2 效果图如下

在这里插入图片描述

2.3 实现代码

package mainimport ("log""os""strconv""time""github.com/lxn/walk". "github.com/lxn/walk/declarative""github.com/lxn/win"
)var mainWindow *walk.MainWindowvar logger *log.Logger// 创建日志服务
func CreateLogService() *log.Logger {file := "log.txt"logFile, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm) // 以读写方式打开文件,如果没有该名称文件则自动创建,以追加的方式写入文件if err != nil {return nil}logger := log.New(logFile, "[logInfo:]", log.LstdFlags|log.Lshortfile) // 将文件设置为loger作为输出return logger
}
func init() {logger = CreateLogService()
}
func main() {var hWnd win.HWND// 主界面MainWindow{AssignTo: &mainWindow,Title:    "ProgressBar Window",Icon:     "icon.png",Size:     Size{Width: 600, Height: 372},Layout:   VBox{},Children: []Widget{PushButton{MinSize: Size{Width: 60, Height: 37},MaxSize: Size{Width: 60, Height: 37},Text:    "显示进度条",OnClicked: func() {doProgress()},},},}.Create()hWnd = mainWindow.Handle()currStyle := win.GetWindowLong(hWnd, win.GWL_STYLE)win.SetWindowLong(hWnd, win.GWL_STYLE, currStyle&(^win.WS_MAXIMIZEBOX))mainWindow.Run()
}var hWnd win.HWND
var dialog *walk.Dialog
var progressBar *walk.ProgressBar
var jindu *walk.LineEdit
var confirm *walk.PushButtonfunc doProgress() {// 进度条弹窗err := Dialog{AssignTo: &dialog,Title:    "进度条 dialog",MinSize:  Size{Width: 300, Height: 200},Layout:   VBox{},Name:     "ProgressBar",Children: []Widget{Label{Text:   "当前进度:",Row:    1,Column: 1,},LineEdit{AssignTo: &jindu,ReadOnly: true,Row:      1,Column:   2,},ProgressBar{AssignTo: &progressBar},PushButton{AssignTo: &confirm,Text:     `执行完毕,退出`,Enabled:  false, //默认不可用OnClicked: func() {// 因为弹窗关闭键被取消,按键关闭dialog.Close(0)},},},}.Create(mainWindow)if err != nil {return}// 禁止关闭hWnd = dialog.Handle()hMenu := win.GetSystemMenu(hWnd, false)win.RemoveMenu(hMenu, win.SC_CLOSE, win.MF_BYCOMMAND)// 开始跑进度条dialog.Starting().Attach(func() {go progressWorker()})dialog.Run()
}func progressWorker() {length := 100// dialog.Synchronize(func() {// 	// progressBar.SetRange(0, int(length))// 	// 进度条value的起止   value到5进度条开始做走,到10停止// 	progressBar.SetRange(5, int(length))// })go func() {defer func() {err := recover()if err != nil {logger.Printf("err:%s", err)}}()// 进度条value的起止   value到0进度条开始做走,到100停止progressBar.SetRange(0, length)}()workWithCallback(length, func(n int64) {go func() {progressBar.WidgetBase.SetToolTipText(strconv.FormatInt(n, 10))progressBar.SetValue(int(n))jindu.SetText(strconv.FormatInt(n, 10))}()})// 跑完后按键可用confirm.SetEnabled(true)
}func workWithCallback(length int, callback func(int64)) {// value从1到100for i := 1; i <= length; i++ {time.Sleep(time.Second)callback(int64(i))}
}

这篇关于教程三:go语言windows gui界面开发之walk 控件学习第二节之进度条的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/700961

相关文章

C语言中联合体union的使用

本文编辑整理自: http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=179471 一、前言 “联合体”(union)与“结构体”(struct)有一些相似之处。但两者有本质上的不同。在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量

51单片机学习记录———定时器

文章目录 前言一、定时器介绍二、STC89C52定时器资源三、定时器框图四、定时器模式五、定时器相关寄存器六、定时器练习 前言 一个学习嵌入式的小白~ 有问题评论区或私信指出~ 提示:以下是本篇文章正文内容,下面案例可供参考 一、定时器介绍 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。 定时器作用: 1.用于计数系统,可

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

[word] word设置上标快捷键 #学习方法#其他#媒体

word设置上标快捷键 办公中,少不了使用word,这个是大家必备的软件,今天给大家分享word设置上标快捷键,希望在办公中能帮到您! 1、添加上标 在录入一些公式,或者是化学产品时,需要添加上标内容,按下快捷键Ctrl+shift++就能将需要的内容设置为上标符号。 word设置上标快捷键的方法就是以上内容了,需要的小伙伴都可以试一试呢!

AssetBundle学习笔记

AssetBundle是unity自定义的资源格式,通过调用引擎的资源打包接口对资源进行打包成.assetbundle格式的资源包。本文介绍了AssetBundle的生成,使用,加载,卸载以及Unity资源更新的一个基本步骤。 目录 1.定义: 2.AssetBundle的生成: 1)设置AssetBundle包的属性——通过编辑器界面 补充:分组策略 2)调用引擎接口API

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

大学湖北中医药大学法医学试题及答案,分享几个实用搜题和学习工具 #微信#学习方法#职场发展

今天分享拥有拍照搜题、文字搜题、语音搜题、多重搜题等搜题模式,可以快速查找问题解析,加深对题目答案的理解。 1.快练题 这是一个网站 找题的网站海量题库,在线搜题,快速刷题~为您提供百万优质题库,直接搜索题库名称,支持多种刷题模式:顺序练习、语音听题、本地搜题、顺序阅读、模拟考试、组卷考试、赶快下载吧! 2.彩虹搜题 这是个老公众号了 支持手写输入,截图搜题,详细步骤,解题必备

《offer来了》第二章学习笔记

1.集合 Java四种集合:List、Queue、Set和Map 1.1.List:可重复 有序的Collection ArrayList: 基于数组实现,增删慢,查询快,线程不安全 Vector: 基于数组实现,增删慢,查询快,线程安全 LinkedList: 基于双向链实现,增删快,查询慢,线程不安全 1.2.Queue:队列 ArrayBlockingQueue:

大语言模型(LLMs)能够进行推理和规划吗?

大语言模型(LLMs),基本上是经过强化训练的 n-gram 模型,它们在网络规模的语言语料库(实际上,可以说是我们文明的知识库)上进行了训练,展现出了一种超乎预期的语言行为,引发了我们的广泛关注。从训练和操作的角度来看,LLMs 可以被认为是一种巨大的、非真实的记忆库,相当于为我们所有人提供了一个外部的系统 1(见图 1)。然而,它们表面上的多功能性让许多研究者好奇,这些模型是否也能在通常需要系

问题-windows-VPN不正确关闭导致网页打不开

为什么会发生这类事情呢? 主要原因是关机之前vpn没有关掉导致的。 至于为什么没关掉vpn会导致网页打不开,我猜测是因为vpn建立的链接没被更改。 正确关掉vpn的时候,会把ip链接断掉,如果你不正确关掉,ip链接没有断掉,此时你vpn又是没启动的,没有域名解析,所以就打不开网站。 你可以在打不开网页的时候,把vpn打开,你会发现网络又可以登录了。 方法一 注意:方法一虽然方便,但是可能会有