wxpython 右键菜单_使用wxPython打造印象笔记(14)笔记本管理
上一篇文章中,我们用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)笔记本管理相关推荐
- wxpython 右键菜单_wxPython menu 详解
本章内容包括: 创建菜单 使用菜单项工作 添加子菜单.弹出菜单和自定义菜单 菜单的设计准则 难以想象一个应用程序的顶部没 有我们常见的以File和Edit开头,以Help结尾的栏目.这太糟糕了.菜单是 ...
- 添加右键菜单_笔记本没有灭屏键?巧在右键菜单添加“关闭显示器”选项
MS酋长的笔记本没有单独的关闭显示器按钮,虽然可以通过运行命令关闭显示器,但毕竟操作比较麻烦.其实我们只需编辑注册表,把关闭显示器命令添加到其中,能够在Win10桌面右键菜单中添加一个"关闭 ...
- openlayer右键菜单_使用OpenLayers3 添加地图鼠标右键菜单
添加右键菜单,首先我们要监听鼠标右键点击的操作,我们知道鼠标右键事件名是 contextmenu,当鼠标在 html 元素之上,点击鼠标右键,便会触发 contextmenu 事件,在 context ...
- java 右键菜单_界面操作--添加右键菜单
[java]代码库package 添加右键菜单; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; impor ...
- 添加右键菜单_添加“复制路径”选项到右键菜单
两种方法,记住方法一与动手方法二,任君选择. 说明:windows 10 专业版(1909),操作系统版本18363.720. 方法一:使用快捷键 按住Shift的同时对选中文件右击,即可看到有&qu ...
- 右键菜单_右键菜单太长会导致电脑卡顿?轻松删除右键菜单无用项
有些人的电脑桌面看起来很整洁有序,结果点一下右键要卡 2秒,弹出来的菜单比脸都长,新建一个文件夹都要找半天. 右键菜单一直是各大软件刷存在感的好地方,因为比起桌面.任务栏和开始菜单,右键菜单使用频 ...
- vfp中treeview右键菜单_用卓语言程序把Sublime Text 3添加到和删除出右键菜单
用卓语言程序把Sublime Text 3添加到和删除出右键菜单 Sublime Text 是一款跨平台代码编辑器(Code Editor)软件.Sublime Text 3既可以编写代码还可以编辑文 ...
- windows管理右键菜单_在Windows 8中使用Windows 7开始菜单,资源管理器和任务管理器...
windows管理右键菜单 If you've tried the Windows 8 Developer Preview and found you don't like the new Start ...
- 取消wps右键菜单_让右键菜单变简洁高效!
软件安装得越来越多 可能会在右键添加许多项目 这就会让右键菜单繁多炫目 比如说下面这个右键菜单: 接下来推荐几款软件,用于优化右键菜单 不仅简洁而且高效,做减法也做加法 一.火绒右键管理 工具分为三大 ...
最新文章
- 一些大佬博客里的个签
- python手机版怎么用-在手机上也可以优雅地进行python编程,你知道吗?
- python向mysql中添加数据_通过python操控MYSQL添加数据,并将数据添加到EXCEL中-阿里云开发者社区...
- HTML期末作业-家乡网站
- Differential Geometry之第八章常Gauss曲率曲面
- simpledateformat_为什么阿里巴巴规定代码中禁用 static 修饰 SimpleDateFormat?
- MySQL 5之存储过程
- Android更新主线程UI的两种方式handler与runOnUiThread()
- Head First 设计模式
- Mysql数据库手册
- 吉林警察学院计算机考研,吉林警察学院怎么样
- python实现斗地主发牌洗牌
- Jshop小程序商城
- Python 打字小游戏开发,来体验不一样的打字游戏乐趣(第二篇)
- 代码审计| HDWiki 漏洞(一)
- aws ec2 mysql 端口_亚马逊:AWS EC2 的 Linux 服务器 开放端口教程
- jsp+java中小学排课系统
- CINTA作业四:群、子群
- 一家化工厂的数字化三级跳 | 产研案例
- element分页组件,搜索过后current-page 绑定的数据变了,但是页面当前页码并没有变的问题