WxPython -- 第五篇 -- 保存文件内容(事件处理)

在上一章中我添加了一个保存文件内容的菜单选项,但遗憾的是当我点击 "保存" 选项时编辑器并不会真正地保存我的文件内容,他只是一个单纯的选项,不会执行任何的关于文件读写的操作。
今天,让我继续改造这个文本编辑器,使它可以保存我的文件内容。

如果忘记了上一章的内容,下面是上一章中的完整源码。

import wx

class MainWindow(wx.Frame):
    def __init__(self, parent, title, size=(600,400)):
        wx.Frame.__init__(self, parent=parent, title=title, size=size)

        # 文本编辑框
        self.text_control = wx.TextCtrl(self, style=wx.TE_MULTILINE)

        # 菜单
        file_menu = wx.Menu()
        file_menu_save = file_menu.Append(wx.ID_SAVE, '保存', '将会保存输入框中的内容')
        window_menu = wx.MenuBar()
        window_menu.Append(file_menu, '文件')
        self.SetMenuBar(window_menu)

        # 窗口状态栏
        self.CreateStatusBar()

        self.Show(True)

app = wx.App()
window = MainWindow(None, '文本编辑器')
app.MainLoop()

嗯...,复习完上一章的内容,别急着打开代码编辑器写代码,先了解事件处理的思想:GUI 应用程序的核心是对各种交互事件的处理程序。应用程序一般在完成建立图形界面 等初始化工作后都会进入一个事件循环(例如WxPython的 app.MainLoop() ),等待事件发生并触发相应的事件处理程序
我一直坚信学习是一个把复杂内容简化后存入脑子的过程,所以上面一段话我简化为:“我转动汽车的钥匙,汽车使用电瓶替我发动了汽车”

额外的提示:事件的概念。
事件!简单的理解,事件就是你的行为所触发的....额.....一些..东西。例如你点击了程序中的一个按钮,可以称为一个 “点击事件”

那我保存文件的过程可以是这样的:

  1. 我点击“保存”菜单选项
  2. WxPython为我调用一个方法,替我把文件内容保存到硬盘中

大概了解后,打开代码编辑器,开始为程序添加处理 “保存” 事件的功能。

import wx

class MainWindow(wx.Frame):
    def __init__(self, parent, title, size=(600,400)):
        wx.Frame.__init__(self, parent=parent, title=title, size=size)

        # 菜单
        file_menu = wx.Menu()
        file_menu_save = file_menu.Append(wx.ID_SAVE, '保存', '将会保存输入框中的内容')
        window_menu = wx.MenuBar()
        window_menu.Append(file_menu, '文件')
        self.SetMenuBar(window_menu)

        # 文本编辑框
        self.text_control = wx.TextCtrl(self, style=wx.TE_MULTILINE)

        # 窗口状态栏
        self.CreateStatusBar()

        # 新内容
        # 关联事件
        self.Bind(wx.EVT_MENU, self.save_file_content, file_menu_save)

        self.Show(True)

    # 新内容
    # 保存输入框架内容
    def save_file_content(self, event):
        print('保存文件')


app = wx.App()
window = MainWindow(None, '文本编辑器')
app.MainLoop()
代码解读

Bind() 方法
函数原型:Bind(event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)
参数event(必须):指定发生的事件类型
参数handler(必须):指定事件发生后调用的事件处理方法
参数source(可选):事件发生者(或者说事件的来源)
参数id(可选):此参数使用wx.ID_ANY让Widgets自行选择
参数id2(可选):此参数使用wx.ID_ANY让Widgets自行选择

self.Bind(wx.EVT_MENU, self.save_file_content, file_menu_save)
参数(wx.EVT_MENU):指定事件类型为菜单事件
参数(self.save_file_content):指定处理事件的方法为save_file_content()
参数(file_menu_save):此参数为file_menu.Append(wx.ID_SAVE, '保存', '将会保存输入框中的内容') 返回的控件的句柄(或者说控件的标识)。

def save_file_content(self, event):
这是处理保存事件的方法,用于保存输入框内容到文件中
参数(event):发生的事件,事件处理方法已被WxPython写死,只能接收一个参数

现在我拥有了一个处理 “保存” 事件的方法: save_file_content(),当我点击菜单中的 “保存” 选项时就会调用此方法来处理我的事件。现在来测试下我们的劳动成功

WxPython -- 第五篇 -- 保存文件内容(事件处理)_第1张图片

点击 “保存” 选项时确实调用了 save_file_content() 来处理我保存事件,而 save_file_content() 的作用就是在控制台打印 保存文件

继续!,完善 save_file_content()

    def save_file_content(self, event):
        '''
        保存文件内容
        与菜单中的保存选项绑定
        '''
        self.dir_name = ''
        fd = wx.FileDialog(self, '把文件保存到何处', self.dir_name, '.txt', 'TEXT file(*.txt)|*.txt', wx.FD_SAVE)
        if fd.ShowModal() == wx.ID_OK:
            self.file_name = fd.GetFilename()
            self.dir_name = fd.GetDirectory()
            try:
                with open(os.path.join(self.dir_name, self.file_name), 'w', encoding='utf-8') as f:
                    text = self.text_control.GetValue()
                    f.write(text)
                    save_msg = wx.MessageDialog(self, '文件已保存', '提示')
            except FileNotFoundError:
                save_msg = wx.MessageDialog(self, '保存失败,无效的保存路径', '提示')    
        else:
            save_msg = wx.MessageDialog(self, '未选择保存路径', '错误')

        save_msg.ShowModal()
        save_msg.Destroy()

小提示:由于使用了os.path.join(),需要 导入os模块
现在save_file_content() 是一个完整的文件保存方法了。
需要注意的是,在完善过程中,我添加了两个新内容,分别是 “文件对话框” 与 “提示对话框,在此章节中,不必学习这两个新内容,但为了文章的可读性,我将会简单介绍下这两个新内容。

文件对话框
# 文件对话框
fd = wx.FileDialog(self, '把文件保存到何处', self.dir_name, '.txt', 'TEXT file(*.txt)|*.txt', wx.FD_SAVE)
# 显示文件对话框
fd.ShowModal()
# 获取文件名
file_name = fd.GetFilename()
# 获取文件所在的目录的路径
dir_name = fd.GetDirectory()

不知道“文件对话框”?,参考下图:
WxPython -- 第五篇 -- 保存文件内容(事件处理)_第2张图片
提示对话框
# 提示对话框
save_msg = wx.MessageDialog(self, '文件已保存', '提示')
# 显示对话框
save_msg.ShowModal()
# 销毁对话框
save_msg.Destroy()

不知道“提示对话框”?参考下图:
WxPython -- 第五篇 -- 保存文件内容(事件处理)_第3张图片

好的,介绍完新内容,进行新一轮测试,来结束今天的内容。

啊~~,完美。
最后附上完整的示例源码

import wx
import os

class MainWindow(wx.Frame):
    def __init__(self, parent, title, size=(600, 400)):
        wx.Frame.__init__(self, parent=parent, title=title, size=size)

        # 文本编辑框
        self.text_control = wx.TextCtrl(self, style=wx.TE_MULTILINE)

        # 菜单
        file_menu = wx.Menu()
        file_menu_save = file_menu.Append(wx.ID_SAVE, '保存', '保存文件内容')
        menu_bar = wx.MenuBar()
        menu_bar.Append(file_menu, '文件')
        self.SetMenuBar(menu_bar)

        # 状态栏
        self.CreateStatusBar()

        # 新内容
        # 新内容添加了事件处理功能
        # Bind()把事件与时间处理方法绑定
        self.Bind(wx.EVT_MENU, self.save_file, file_menu_save)

        self.Show()

    def save_file(self, event):
        '''
        保存文件内容
        与菜单中的保存选项绑定
        '''
        self.dir_name = ''
        fd = wx.FileDialog(self, '把文件保存到何处', self.dir_name, 
                '.txt', 'TEXT file(*.txt)|*.txt', wx.FD_SAVE)
        if fd.ShowModal() == wx.ID_OK:
            self.file_name = fd.GetFilename()
            self.dir_name = fd.GetDirectory()
            try:
                with open(os.path.join(self.dir_name, self.file_name), 'w', encoding='utf-8') as f:
                    text = self.text_control.GetValue()
                    f.write(text)
                    save_msg = wx.MessageDialog(self, '文件已保存', '提示')
            except FileNotFoundError:
                save_msg = wx.MessageDialog(self, '保存失败,无效的保存路径', '提示')    
        else:
            save_msg = wx.MessageDialog(self, '未选择保存路径', '错误')

        save_msg.ShowModal()
        save_msg.Destroy()


app = wx.App()
main_window = MainWindow(None, '文本编辑器')
app.MainLoop()
WxPython -- 第五篇 -- 保存文件内容(事件处理)_第4张图片

你可能感兴趣的:(WxPython -- 第五篇 -- 保存文件内容(事件处理))