Designing task list

我们在这一节中将会设计一个,左边是列表,右边列表中代办事项的具体内容

实现效果如图:

实现该需要使用总共用了两个文件,一个task_list.go

package mainimport ("fyne.io/fyne/v2""fyne.io/fyne/v2/app""fyne.io/fyne/v2/container""fyne.io/fyne/v2/theme""fyne.io/fyne/v2/widget""time"
)type taskApp struct {data *taskList// 记录当前代办事项visible []*task// 当前选中的taskcurrent *tasktasks *widget.List// Entry widget allows simple text to be input when focused.title, description, due *widget.Entrycategory                *widget.Selectpriority                *widget.RadioGroupcompletion              *widget.Slider
}func (a *taskApp) refreshData() {// hide donea.visible = a.data.remaining()a.tasks.Refresh()
}func (a *taskApp) setTask(t *task) {// 最新设置的那个task就是当前的代办列表a.current = t// 将data的title设置到APP的title中a.title.SetText(t.title)a.description.SetText(t.description)a.category.SetSelected(t.category)if t.priority == midPriority {a.priority.SetSelected("Mid")} else if t.priority == highPriority {a.priority.SetSelected("High")} else {a.priority.SetSelected("Low")}a.due.SetText(formatData(t.due))a.completion.Value = t.completiona.completion.Refresh()
}func formatData(date *time.Time) string {if date == nil {return ""}return date.Format(dateFormat)
}func (a *taskApp) makeUI() fyne.CanvasObject {a.tasks = widget.NewList(func() int {return len(a.visible)},func() fyne.CanvasObject {return container.NewHBox(widget.NewCheck("", func(bool) {}),widget.NewLabel("TODO ITtem x"))},func(i widget.ListItemID, c fyne.CanvasObject) {task := a.visible[i]box := c.(*fyne.Container)check := box.Objects[0].(*widget.Check)check.Checked = task.donecheck.OnChanged = func(done bool) {task.done = donea.refreshData()}labelData := box.Objects[1].(*widget.Label)labelData.SetText(task.title)})// 当选中一个list的时候,调用该回调函数// 选中哪个list之后,将界面上需要显示的都更换成当前ID 的list对象a.tasks.OnSelected = func(id widget.ListItemID) {a.setTask(a.visible[id])}// 标题支持输入a.title = widget.NewEntry()a.title.OnChanged = func(text string) {if a.current == nil {return}// 更新当前选中的标题a.current.title = texta.tasks.Refresh()}a.description = widget.NewMultiLineEntry()a.description.OnChanged = func(text string) {if a.current == nil {return}a.current.description = text}a.category = widget.NewSelect([]string{"Home"}, func(cat string) {if a.current == nil {return}a.current.category = cat})a.priority = widget.NewRadioGroup([]string{"Low", "Mid", "High"}, func(pri string) {if a.current == nil {return}if pri == "Mid" {a.current.priority = midPriority} else if pri == "High" {a.current.priority = highPriority} else {a.current.priority = lowPriority}})a.due = widget.NewEntry()a.due.Validator = dateValidatora.due.OnChanged = func(str string) {if a.current == nil {return}if str == "" {a.current.due = nil} else {date, err := time.Parse(dateFormat, str)if err != nil {a.current.due = &date}}}a.completion = widget.NewSlider(0, 100)a.completion.OnChanged = func(done float64) {if a.current == nil {return}a.current.completion = done}details := widget.NewForm(widget.NewFormItem("Title", a.title),widget.NewFormItem("Description", a.description),widget.NewFormItem("Category", a.category),widget.NewFormItem("Priority", a.priority),widget.NewFormItem("Due", a.due),widget.NewFormItem("Completion", a.completion),)toolBar := widget.NewToolbar(widget.NewToolbarAction(theme.ContentAddIcon(), func() {task := &task{title: "New task"}a.data.add(task)a.setTask(task)a.refreshData()}),)return container.NewBorder(toolBar, nil, a.tasks, nil, details)
}/*** 创建一个代办事项的APP*/func main() {a := app.New()w := a.NewWindow("Task List")data := dummyData()tasks := &taskApp{data: data, visible: data.remaining()}w.SetContent(tasks.makeUI())// 若是首次启动的时候,项目大于0就显示首个listif len(data.remaining()) > 0 {tasks.setTask(data.remaining()[0])}w.ShowAndRun()
}

还有一个是data.go

package mainimport "time"const (dateFormat = "02 Jan 06 15:04"lowPriority  = 0midPriority  = 1highPriority = 2
)func dateValidator(text string) error {_,err := time.Parse(dateFormat, text)return err
}type task struct {// 定义标题和描述语句title, description string// 该任务是否已经完成done                boolcategory         stringpriority         intdue             *time.Timecompletion           float64
}// 定义任务链表的切片
type taskList struct {tasks []*task
}// 添加任务,新添加的任务放到列表头
func (l *taskList) add(t *task) {// 使用t初始化一个一样的切片,并将原有的切片添加到后面l.tasks = append([]*task{t}, l.tasks...)
}/* 获取剩余没有完成的任务列表 */
func (l *taskList) remaining() []*task {var items []*taskfor _, task := range l.tasks {if !task.done {items = append(items, task)}}return items
}/* 获取已经完成的任务列表 */
func (l *taskList) done() []*task {var items []*taskfor _, task := range l.tasks {if task.done {items = append(items, task)}}return items
}func dummyData() *taskList {return &taskList{tasks: []*task{{title: "Nearly done", description: "you can tick my checkbox and I will be marked as done and disappear"},{title: "Functions", description: "Tap the plus icon above to add a new task, or tap the munus icon to remove this one"},},}
}

下面会讲解下具体思路

如图,我们首先需要创建一个toolbar,需要使用到函数NewToolbar,toolbar里面需要放置一个添加按钮

toolBar := widget.NewToolbar(widget.NewToolbarAction(theme.ContentAddIcon(), func() {task := &task{title: "New task"}a.data.add(task)a.setTask(task)a.refreshData()}),
)

然后添加面板中各个入口的对象

// 当选中一个list的时候,调用该回调函数
// 选中哪个list之后,将界面上需要显示的都更换成当前ID 的list对象
a.tasks.OnSelected = func(id widget.ListItemID) {a.setTask(a.visible[id])
}
// 标题支持输入
a.title = widget.NewEntry()
a.title.OnChanged = func(text string) {if a.current == nil {return}// 更新当前选中的标题a.current.title = texta.tasks.Refresh()
}a.description = widget.NewMultiLineEntry()
a.description.OnChanged = func(text string) {if a.current == nil {return}a.current.description = text
}a.category = widget.NewSelect([]string{"Home"}, func(cat string) {if a.current == nil {return}a.current.category = cat
})a.priority = widget.NewRadioGroup([]string{"Low", "Mid", "High"}, func(pri string) {if a.current == nil {return}if pri == "Mid" {a.current.priority = midPriority} else if pri == "High" {a.current.priority = highPriority} else {a.current.priority = lowPriority}
})a.due = widget.NewEntry()
a.due.Validator = dateValidator
a.due.OnChanged = func(str string) {if a.current == nil {return}if str == "" {a.current.due = nil} else {date, err := time.Parse(dateFormat, str)if err != nil {a.current.due = &date}}
}a.completion = widget.NewSlider(0, 100)
a.completion.OnChanged = func(done float64) {if a.current == nil {return}a.current.completion = done
}details := widget.NewForm(widget.NewFormItem("Title", a.title),widget.NewFormItem("Description", a.description),widget.NewFormItem("Category", a.category),widget.NewFormItem("Priority", a.priority),widget.NewFormItem("Due", a.due),widget.NewFormItem("Completion", a.completion),
)toolBar := widget.NewToolbar(widget.NewToolbarAction(theme.ContentAddIcon(), func() {task := &task{title: "New task"}a.data.add(task)a.setTask(task)a.refreshData()}),
)

golang的GUI库,使用go-fyne设计一个代办事项APP相关推荐

  1. golang桌面gui库fyne使用

    golang桌面gui库fyne使用 使用 初始项目 新建项目文件夹fyna 执行go mod init 执行go get fyne.io/fyne/v2 执行go mod tidy 创建main.g ...

  2. Android -- 每日一问:如何设计一个照片上传 app ?

    经典回答 把自己放在一个面试官的角度,自己先实现一次这个 App ,然后自己总结一下你在这次实现中需要哪些能力.需要注意哪些事项.最后,再回过头来看,如果你是面试官,你希望面试者怎么回答才算是符合你的 ...

  3. 【Golang】Go语言Windows GUI库XCGUI,DirectUI设计思想,高度自定义界面,支持Direct2D硬件加速

    Github地址 https://github.com/twgh/xcgui 介绍 本库封装自炫彩界面库,功能丰富(1000多个API接口),简单易用,轻量级,高度DIY自定义,支持一键换肤. 炫彩界 ...

  4. 请设计一个宠物社交APP。

    宠物社交以宠物为核心,但是并不意味着只有养宠物的人才能参与此类社交. 可以将用户群分为两类:养宠物的人和喜欢宠物想看想养宠物的人. 我设计的宠物APP核心功能如下: 1.宠物主人可以在社区内上传自己宠 ...

  5. python自带gui_一个极简易上手的 Python GUI 库

    原标题:一个极简易上手的 Python GUI 库 很多同学学了 Python 之后都想开发带界面的程序,也就是 GUI 应用.一般用的比较多的 GUI 库是 Tkinter(Python 自带)和 ...

  6. Golang的viper库

    Golang的viper库 1.作用 viper 是一个配置解决方案,拥有丰富的特性: 支持 JSON/TOML/YAML/HCL/envfile/Java properties 等多种格式的配置文件 ...

  7. golang开发GUI桌面应用fyne(三)

    文档 https://developer.fyne.io/started/packaging 画布 Canvas 在 Fyne 中,我们向窗体设置内容的方法 window.SetContent(Can ...

  8. python界面设计资源库_python GUI库图形界面开发之PyQt5 Qt Designer工具(Qt设计师)详细使用方法及Designer ui文件转py文件方法...

    PyQt5 Qt Designer (Qt设计师) PyQt5是对Qt所有类进行封装, Qt能开发的东西, PyQt都能开发. Qt是强大的GUI库之一, 用C++开发, 并且跨平台. PyQt双许可 ...

  9. python图形界面设计代码_python GUI库图形界面开发之PyQt5 Qt Designer工具(Qt设计师)详细使用方...

    PyQt5 Qt Designer (Qt设计师) PyQt5是对Qt所有类进行封装, Qt能开发的东西, PyQt都能开发. Qt是强大的GUI库之一, 用C++开发, 并且跨平台. PyQt双许可 ...

最新文章

  1. 【radar】毫米波雷达相关数据集(检测、跟踪、里程计、SLAM、定位、场景识别)总结(1)
  2. 在一般处理程序(handler)中获取session的方法
  3. BRCM5.02编译十:cmake: command not found
  4. 国内主流.NET CMS系统整理
  5. 使用redis做为MySQL的缓存
  6. 如何在JSF中实现自定义密码强度指示器
  7. 清华CrossWOZ,助你徒手搭建任务导向对话系统
  8. 【MySQL】MySQL监视器无法启动的可能情况
  9. 【消息队列之rabbitmq】Rabbitmq之消息可靠性投递和ACK机制实战
  10. Unity中Temporal AA
  11. cdev_alloc和cdev_init
  12. 小鹏汽车北京车展发布免费加电、电池租赁计划以及低空飞行汽车
  13. apache   和Tomcat的区别
  14. 在Rammap(内存分析工具)的基础上实现自动优化
  15. 实现安卓中TextView,EditText中数字的数码管字体显示
  16. megui 2913 汉化版 压制特效的方法
  17. 关于DSP28335CCS6编译报错error #10099-D: program will not fit into available memory.
  18. C++数据采集软件和数据显示软件(TCP通信)
  19. 微信小程序实现拍照功能
  20. Retbleed:针对英特尔和AMD处理器的推断性执行攻击

热门文章

  1. 2008春节长白山哈尔滨雪乡游
  2. 推荐系统——开源代码
  3. CH4402 小Z的袜子(莫队)
  4. sqlserver 跨服务器备份表
  5. 1313 质因数分解 2012年NOIP全国联赛普及组
  6. JSP连接数据库 - MySQL
  7. 没牙虎小apple的幸福生活
  8. 使用存储过程将文本导入数据库表
  9. LSTM拟合正弦曲线代码(转载)
  10. matlab 中imagesc的用法