上一篇文章中,我们用peewee对数据库建模并创建了数据库,然后成功的加载了默认笔记本。这篇文章将完成笔记本的管理功能,分为创建笔记本,修改笔记本,删除笔记本这三个功能。创建笔记本编辑笔记本删除笔记本

右键菜单

首先我们来实现右键菜单功能,编辑 views / note_tree.py 文件,在 __init__ 方法中添加 self._init_popup_menu() 用于初始化右键菜单,实现如下:

def _init_popup_menu(self):

self.menu = wx.Menu()

self.menu_id_create_notebook = wx.NewIdRef()

self.menu_id_edit_notebook = wx.NewIdRef()

self.menu_id_delete_notebook = wx.NewIdRef()

self.menu.Append(self.menu_id_create_notebook, '创建笔记本')

self.menu.Append(self.menu_id_edit_notebook, '编辑笔记本')

self.menu.Append(self.menu_id_delete_notebook, '删除笔记本')

右键菜单有三个菜单项,每个菜单项都分配了ID,其目的是为了绑定 wx.MENU 事件,再定义一个 _init_event 方法,用来初始化右键菜单的事件响应。

def _init_event(self):

self.Bind(wx.EVT_CONTEXT_MENU, self._show_popup_menu)

self.Bind(wx.EVT_MENU, self._create_notebook, id=self.menu_id_create_notebook)

self.Bind(wx.EVT_MENU, self._edit_notebook, id=self.menu_id_edit_notebook)

self.Bind(wx.EVT_MENU, self._delete_notebook, id=self.menu_id_delete_notebook)

当右键菜单事件 wx.EVT_CONTEXT_MENU 触发时,调用 _show_popup_menu 方法显示右键菜单。

def _show_popup_menu(self, _):

self.PopupMenu(self.menu)

新建笔记本

思路分析:点击“创建笔记本”时,将显示表单弹窗,填写完成之后点击表单确定按钮,数据库将新增一条 notebook 记录,并且笔记本导航栏将新增一个节点。

数据库新增由peewee实现,导航栏的节点管理通过 CustomTreeCtrl 提供的API即可完成,数据库记录与节点之间还需要建立联系,例如删除某个笔记本时,显然需要知道这个笔记本对应的数据库记录是哪个,这样才可以将其从数据库中删除。

我们之前通过 self.AppendItem(self.root, notebook.name) 实际上创建了一个 customtreectrl.GenericTreeItem 对象,为了和数据库建立联系,只需要设置一下data参数即可,self.AppendItem(self.root, notebook.name, data=notebook),现在节点就保存了对应的数据库记录了。如果需要获取节点关联的数据库记录,只需调用 GetData 方法即可。

节点和数据库之间已经建立了联系,剩下的工作主要涉及UI层面的操作。

新建 views / notebook_dialog.py 文件,用于表示笔记本表单弹窗。代码如下:

import wx

class NotebookDialog(wx.Dialog):

def __init__(self, parent, notebook=None):

title = '编辑笔记本' if notebook else '新建笔记本'

super().__init__(parent, title=title)

main_sizer = wx.BoxSizer(wx.VERTICAL)

g_sizer = wx.FlexGridSizer(cols=2,gap=(10, 10))

g_sizer.AddGrowableCol(1)

g_sizer.Add(wx.StaticText(self, label='名称'))

self.tc_name = wx.TextCtrl(self, size=(400,-1))

g_sizer.Add(self.tc_name, flag=wx.EXPAND)

g_sizer.Add(wx.StaticText(self, label='描述'))

self.tc_description = wx.TextCtrl(self, size=(400, 160),style=wx.TE_MULTILINE)

g_sizer.Add(self.tc_description, flag=wx.EXPAND)

main_sizer.Add(g_sizer, flag=wx.EXPAND|wx.ALL, border=10)

btn_sizer = wx.StdDialogButtonSizer()

btn_sizer.AddButton(wx.Button(self, wx.ID_CANCEL, '取消'))

ok_button = wx.Button(self, wx.ID_OK, '确定')

ok_button.SetDefault()

btn_sizer.AddButton(ok_button)

btn_sizer.Realize()

main_sizer.Add(btn_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, border=5)

if notebook:

self.tc_name.SetValue(notebook.name)

self.tc_description.SetValue(notebook.description)

self.tc_name.SelectAll()

self.SetSizer(main_sizer)

main_sizer.Fit(self)

self.CenterOnScreen()

self.Bind(wx.EVT_BUTTON, self._on_save, id=wx.ID_OK)

def get_name(self):

return self.tc_name.GetValue().strip()

def get_description(self):

return self.tc_description.GetValue().strip()

def _on_save(self, e):

if self.get_name():

self.EndModal(wx.ID_OK)

相应的 _create_notebook 方法如下:

def _create_notebook(self, _):

with NotebookDialog(self) as dialog:

if dialog.ShowModal() == wx.ID_OK:

notebook = Notebook.create(

name=dialog.get_name(),

description=dialog.get_description(),

parent_id=self.GetSelection().GetData().id)

item = self.AppendItem(self.GetSelection(), notebook.name, data=notebook)

self.DoSelectItem(item)

Notebook.create 创建了一个 notebook 对象,self.GetSelection 方法用于获取当前选中的节点。通过 AppendItem 方法将这个对象保存到节点里面,然后使用 DoSelectItem 方法选中这个节点。

parent_id 就是节点绑定对象的id,但千万别忘了,根节点(“所有笔记“)并没有绑定任何对象啊,因此如果在根节点上右键创建笔记本的话,就会报错,此时 GetData 为 None,根本就没有 id 属性!

只需要将根节点绑定到一个Notebook对象即可:

self.root = self.AddRoot("所有笔记", data=Notebook())

编辑笔记本

编辑笔记本和新建笔记本类似,数据库更新和节点更新有所不同,整体思路都是一样的。

_edit_notebook 方法如下:

def _edit_notebook(self, _):

notebook = self.GetSelection().GetData()

with NotebookDialog(self, notebook) as dialog:

if dialog.ShowModal() == wx.ID_OK:

notebook.name = dialog.get_name()

notebook.description = dialog.get_description()

notebook.save()

self.SetItemText(self.GetSelection(), notebook.name)

但需要注意的是:在更新之后 notebook 的 updated_at 属性值并没有变化,而我们预期 updated_at 是数据库记录更新时间,因为peewee保存数据时会调用 save 方法,所以我们只需要定义 save 方法即可,对 models / base_model.py 进行编辑:

def save(self, *args, **kwargs):

self.updated_at = datetime.datetime.now()

return super().save(*args, **kwargs)

再次编辑并保存笔记本,此时的 updated_at 属性已发生变化。

删除笔记本

删除笔记本操作首先会弹出一个对话框,点击确定之后删除数据库记录并移除相应的节点。对话框可以通过 wx.MessageDialog 实现,删除记录可以调用 peewee 提供的 delete_instance 方法。_delete_notebook 方法如下:

def _delete_notebook(self, _):

dialog = wx.MessageDialog(self, '此笔记本中的任何笔记都将被删除,这个操作不能恢复。', '确定要删除吗?',style=wx.OK|wx.CANCEL|wx.CANCEL_DEFAULT)

dialog.SetOKCancelLabels('确定', '取消')

if dialog.ShowModal() == wx.ID_OK:

self.GetSelection().GetData().delete_instance()

self.Delete(self.GetSelection())

加载多层级笔记本

我们首先添加多层级笔记本数据,如下操作:

重新运行程序,发现数据显示有问题了:

这是因为加载笔记本数据的时候,不支持多层级数据结构。我们修改 _load_notebooks 方法,让它递归生成子节点:

def _load_notebooks(self, parent_node, parent_id):

child_notebooks = Notebook.select().where(Notebook.parent_id == parent_id)

for notebook in child_notebooks:

item = self.AppendItem(parent_node, notebook.name, data=notebook)

self._load_notebooks(item, notebook.id)

在 __init__ 方法中调用:

self.root = self.AddRoot("所有笔记", data=Notebook())

self._load_notebooks(self.root, None)

再次运行程序,发现笔记本已经正确显示了。

总结

笔记本管理功能由数据库管理和UI管理两部分组成,peewee负责数据库管理, CustomTreeCtrl 负责UI管理,数据库和UI通过 customtreectrl.GenericTreeItem 的 data 参数很方便的建立了联系。

下一篇文章将介绍如何保存笔记数据。

wxpython 右键菜单_使用wxPython打造印象笔记(14)笔记本管理相关推荐

  1. wxpython 右键菜单_wxPython menu 详解

    本章内容包括: 创建菜单 使用菜单项工作 添加子菜单.弹出菜单和自定义菜单 菜单的设计准则 难以想象一个应用程序的顶部没 有我们常见的以File和Edit开头,以Help结尾的栏目.这太糟糕了.菜单是 ...

  2. 添加右键菜单_笔记本没有灭屏键?巧在右键菜单添加“关闭显示器”选项

    MS酋长的笔记本没有单独的关闭显示器按钮,虽然可以通过运行命令关闭显示器,但毕竟操作比较麻烦.其实我们只需编辑注册表,把关闭显示器命令添加到其中,能够在Win10桌面右键菜单中添加一个"关闭 ...

  3. openlayer右键菜单_使用OpenLayers3 添加地图鼠标右键菜单

    添加右键菜单,首先我们要监听鼠标右键点击的操作,我们知道鼠标右键事件名是 contextmenu,当鼠标在 html 元素之上,点击鼠标右键,便会触发 contextmenu 事件,在 context ...

  4. java 右键菜单_界面操作--添加右键菜单

    [java]代码库package 添加右键菜单; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; impor ...

  5. 添加右键菜单_添加“复制路径”选项到右键菜单

    两种方法,记住方法一与动手方法二,任君选择. 说明:windows 10 专业版(1909),操作系统版本18363.720. 方法一:使用快捷键 按住Shift的同时对选中文件右击,即可看到有&qu ...

  6. 右键菜单_右键菜单太长会导致电脑卡顿?轻松删除右键菜单无用项

    ​ 有些人的电脑桌面看起来很整洁有序,结果点一下右键要卡 2秒,弹出来的菜单比脸都长,新建一个文件夹都要找半天. 右键菜单一直是各大软件刷存在感的好地方,因为比起桌面.任务栏和开始菜单,右键菜单使用频 ...

  7. vfp中treeview右键菜单_用卓语言程序把Sublime Text 3添加到和删除出右键菜单

    用卓语言程序把Sublime Text 3添加到和删除出右键菜单 Sublime Text 是一款跨平台代码编辑器(Code Editor)软件.Sublime Text 3既可以编写代码还可以编辑文 ...

  8. windows管理右键菜单_在Windows 8中使用Windows 7开始菜单,资源管理器和任务管理器...

    windows管理右键菜单 If you've tried the Windows 8 Developer Preview and found you don't like the new Start ...

  9. 取消wps右键菜单_让右键菜单变简洁高效!

    软件安装得越来越多 可能会在右键添加许多项目 这就会让右键菜单繁多炫目 比如说下面这个右键菜单: 接下来推荐几款软件,用于优化右键菜单 不仅简洁而且高效,做减法也做加法 一.火绒右键管理 工具分为三大 ...

最新文章

  1. 一些大佬博客里的个签
  2. python手机版怎么用-在手机上也可以优雅地进行python编程,你知道吗?
  3. python向mysql中添加数据_通过python操控MYSQL添加数据,并将数据添加到EXCEL中-阿里云开发者社区...
  4. HTML期末作业-家乡网站
  5. Differential Geometry之第八章常Gauss曲率曲面
  6. simpledateformat_为什么阿里巴巴规定代码中禁用 static 修饰 SimpleDateFormat?
  7. MySQL 5之存储过程
  8. Android更新主线程UI的两种方式handler与runOnUiThread()
  9. Head First 设计模式
  10. Mysql数据库手册
  11. 吉林警察学院计算机考研,吉林警察学院怎么样
  12. python实现斗地主发牌洗牌
  13. Jshop小程序商城
  14. Python 打字小游戏开发,来体验不一样的打字游戏乐趣(第二篇)
  15. 代码审计| HDWiki 漏洞(一)
  16. aws ec2 mysql 端口_亚马逊:AWS EC2 的 Linux 服务器 开放端口教程
  17. jsp+java中小学排课系统
  18. CINTA作业四:群、子群
  19. 一家化工厂的数字化三级跳 | 产研案例
  20. element分页组件,搜索过后current-page 绑定的数据变了,但是页面当前页码并没有变的问题

热门文章

  1. 微信小程序●云开发部署攻略
  2. 股票期货量化数据文档大全覆盖国内6大交易的史数据和实时行情
  3. 一个PHP程序员的职业生涯技术提升阶梯规划方案
  4. 大数据工程师修炼笔记
  5. SpringBoot 项目单元测试
  6. Python制作回合制手游外挂简单教程(中)
  7. 高斯消元法(高斯·约当消元法)(浮点)
  8. 【NOIP2017提高A组集训10.25】摘Galo (树形dp)
  9. 【看好了】如何使用fiddler实现手机抓包,Filters过滤器!
  10. 艾司博讯:拼多多机器人客服在哪里