js创建file对象_使用wxPython打造印象笔记(15)创建和保存笔记

8073f06c2eaff4c6b6a677cfafd5e29a.png

笔记本管理功能已经实现了,接下来我们研究如何保存笔记内容。先来看一下最终效果:

2df90a75242030d761a69db3903284d8.gif

点击新建笔记按钮,中间的笔记列表中就会出现该笔记的预览面板,输入标题和内容,预览面板上的内容会同步更新,笔记内容也会自动保存。

获取笔记内容

文本编辑器的内容实现就是HTML代码,可以借助js获取这段HTML代码,然后通过webview的js绑定传递给Python。

保存笔记

笔记的标题保存在数据库里面,笔记内容是HTML形式的富文本,可以直接保存在文件里面。将富文本去掉HTML标签得到纯文本,用于预览,所以预览文本也可以保存在文件里面。这样一条笔记就会包含两个文件,将它们放在一个文件夹里面,文件夹名称即为笔记本的uuid值。

跨组件通信

在 NavPanel 中点击新建笔记按钮时,就会创建一条Note记录,这条记录如何传递给笔记列表 ListPanel 组件呢?对于这类跨组件通信问题,wxPython 中推荐的做法是使用发布订阅模式。

NavPanel 在创建笔记之后发出一个"note.created" 消息,消息中包含Note对象;在 ListPanel 订阅了 "note.created" 消息,当收到消息时,就能提取出 Note 对象。

我们在这里使用PyPubSub来简化跨组件通信。

参数设置

上面三个问题回答之后,就可以安心开发了。在之前的文章中,数据库文件路径默认为 "data / note.db",现在又涉及到了笔记保存位置,最好能将这些参数集中管理。Python提供了ConfigParser来管理配置文件,在根目录下新建一个 config.py 文件,内容如下:

import 

然后将 models / base_model.py 里面的数据库文件路径相应修改:

database 

运行主程序,可以发现根目录下生成了一个 config.ini 文件,内容如下:

[app]
data_dir = data
note_dir = notes

[database]
db_file = data/note.db

Note模型调整

根据上面的思路,每条笔记创建的时候就应该完成三件事:

  1. 生成uuid
  2. 生成一个空白文件用于保存富文本
  3. 生成一个空白文件用于保存纯文本(用于预览)

models / note.py 内容如下:

from 

这里的 set_content 方法用于保存笔记内容。

新建笔记

原来的新建笔记按钮没有图标,接下来在按钮前面添加一个图标,首先下载图片:

31cf3baf2c4c2388d4eaa583bee6e5af.png
add_note.png

然后运行 encode_bitmap_util.py,修改 views / nav_panel.py 文件:

self

图标已经添加好了,接下来添加事件处理方法:

self

笔记需要一个 notebook_id 属性,可以通过 NoteTree 组件获取,修改 views / note_tree.py :

@property

调用 Note.create 方法就可以创建笔记了,笔记创建好了之后需要传递给笔记列表 ListPanel,由上面的分析可知,还需要 pypubsub 这个包,安装一下:

pip install PyPubSub

安装好了之后,通过 from pubsub import pub 导入pub模块:

note = Note.create(notebook_id=self.note_tree.notebook_id)
pub.sendMessage('note.created', note=note)

views / nav_panel.py 代码如下:

import 

在笔记列表中显示

运行主程序,点击新建笔记按钮之后,发现notes文件夹下新建了一些文件:

1587433f35deb9d8674c23ae7b329dbf.png

说明笔记相关的文件创建成功了,不过笔记列表中并没有显示这条笔记。

修改 views / list_panel.py 文件,移除之前的测试代码:

9ac4fee6b5d96075eea262b5e6358310.png

可以看到,我们使用 pub.subscribe 方法来订阅 note.created 主题,并在 _on_note_created 方法中提取到了 NavPanel 新建笔记时传过来的Note对象。

再次运行主程序,点击新建按钮,发现笔记列表出现了一个预览窗体,但显示的是测试文字,接下来修改 views / note_preview_panel.py,移除测试代码:

fe75a3044209521539e239bfdfdba5fa.png

再次运行程序,点击新建按钮,可以正常显示了:

9a5ee68e8d94c75387f18b24f39c9138.gif

保存笔记

如果在标题输入框或者文本编辑器中输入文字时,这些文字并没有保存到数据库或者文件里面。 为了能够保存内容,首先编辑器要能够加载笔记。

修改 views / text_editor.py,订阅 note.created 消息:

pub

load_note 方法用于加载笔记标题和笔记富文本,标题很容易更新,调用 wx.TextCtrl 的 ChangeValue (不会触发 wx.EVT_TXT 事件)即可,富文本如何更新呢?

根据前面的讨论,富文本实际上就是编辑器节点的HTML代码,因此可以通过webview调用相应的js方法来更新HTML,编辑 assets / text_editor / core.js,获取编辑器的DOM节点,然后定义一个更新编辑器内容的函数:

let 

text_editor.py 的 load_content 方法如下:

def 

其中self.note 在初始化的时候默认为 None。

点击新建笔记按钮时,文本编辑器就可以获取到对应的Note对象,并将其保存在了 note 成员变量中。

为了能够保存标题,我们只需要监听标题内容更新事件,并更新note成员变量即可:

self

注意在这里,我们发送了 note.updated 消息,后面的预览窗体同步功能需要用到。

每当标题变化,数据库里面的title字段就会相应更新。同理,当富文本编辑器的内容变化时,笔记的文件内容也会更新。

如何监听编辑器内容变化呢?和之前的监听编辑器格式变化一样,可以借助quill来实现,编辑 assets / text_editor / core.js,添加如下回调方法:

quill

注意:当编辑器内容发生变化时,就会更新笔记文件。当调用 quill.load_content 方法加载笔记时,也会触发 text-change 事件,但我们不希望第一次加载笔记时就立即更新笔记,所以添加了if判断,quill.load_content 的 source 为 api。

在 views / text_editor.py 中添加js绑定:

# 修改 __init__

现在我们来测试一下:

686ba6ee80019bad7614fc3ec581f3dc.gif

然后查看文件 content.html 内容如下:

<p><span style="font-size: 18px;">hello </span><strong style="font-size: 18px;">world</strong></p>

snippet.txt 内容如下:

hello world

和预期一致!

笔记预览同步更新

我们观察到在编辑器中输入标题和内容时,笔记列表里面的预览区域并没有同步更新,如何解决这个问题?

我们只需要获取到更新之后的笔记对象即可,订阅 note.updated 主题!编辑 views / note_preview_panel.py 文件:

# 修改 __init__

再次测试一下,预览面板可以同步更新了:

1d94ed8bf7642080e0cfd3e5bc715bff.gif

总结

创建和保存笔记功能已经实现了,但还可以优化:例如在编辑器中连续输入文字时,会不停的触发回调方法来执行文件保存操作,理想的状态应该是连续输入文字的间隔时间大于2秒或者更长时,才执行回调方法,以便节省程序开销。当然实际上可以通过JavaScript防抖动函数来实现,这里就不再介绍了。

后面的文章中将会涉及到如何管理笔记列表。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值