【日常收支账本】【Day05】编辑账本界面增加删除、更新记录功能——提高代码复用性

这篇具有很好参考价值的文章主要介绍了【日常收支账本】【Day05】编辑账本界面增加删除、更新记录功能——提高代码复用性。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、项目地址

https://github.com/LinFeng-BingYi/DailyAccountBook

二、新增

1. 增加删除记录功能

1.1 功能详述

  • 点击删除按钮后,获取对应行的数据组成字典,用字典的键值对匹配到对应日期的记录元素;
  • 接着用该字典数据冲正存款账户余额(实现思路为新增记录时的反向操作),同时删除记录元素;
  • 最后再更新表格。

1.2 代码实现

    def deleteTableRow(self, triggeredBtn, tableWidget):
        print("触发了删除按钮")
        # 获取触发信号的控件所在行号
        current_row = tableWidget.indexAt(triggeredBtn.parent().pos()).row()
        if tableWidget == self.tableWidget_expense:
            const_class = expenseConst
            action = 'expense'
        elif tableWidget == self.tableWidget_income:
            const_class = incomeConst
            action = 'income'
        elif tableWidget == self.tableWidget_movement:
            const_class = movementConst
            action = 'movement'
        else:
            print('未知控件触发新增按钮!')
            return
        # 获取待删除行的数据
        old_data_dict = self.getExistTableCell(tableWidget, current_row, const_class)
        if old_data_dict is None:
            print("获取待删除数据失败!!")
            return
        print("待删除记录内容为: \n", old_data_dict)

        if self.file_processor.deleteRecord(old_data_dict, self.dateEdit.text().replace('/', ''), action):
            print("删除成功!")
            # 把删除结果写入文件
            self.file_processor.writeXMLFile(self.lineEdit_file_path.text())

            # 更新self.file_parse_result以及记录表
            records_list = self.file_parse_result[action + 's']
            records_list.pop(current_row)
            self.updateRecordTable(tableWidget, records_list, const_class)

其中处理xml文件的方法代码如下:

    def deleteRecord(self, old_record_dict, date_str, action):
        e_date = self.getSpecificDateElement(date_str)
        if isinstance(e_date, int):
            print("未找到这一天的数据!")
            return False

        if action == 'expense':
            action_path = ".//expenses"
            record_path = """.//expense[@necessity='{}'][@associatedFund='{}'][value='{}'][category='{}'][detail='{}'][describe='{}'][from='{}']""".format(
                old_record_dict['necessity'],
                old_record_dict['associatedFund'],
                old_record_dict['value'],
                old_record_dict['category'],
                old_record_dict['detail'],
                old_record_dict['describe'],
                old_record_dict['from'])
        elif action == 'income':
            action_path = ".//incomes"
            record_path = """.//income[@associatedFund='{}'][value='{}'][category='{}'][detail='{}'][describe='{}'][to='{}']""".format(
                old_record_dict['associatedFund'],
                old_record_dict['value'],
                old_record_dict['category'],
                old_record_dict['detail'],
                old_record_dict['describe'],
                old_record_dict['to'])
        elif action == 'movement':
            action_path = ".//movements"
            record_path = """.//movement[value='{}'][detail='{}'][describe='{}'][from='{}'][to='{}']""".format(
                old_record_dict['value'],
                old_record_dict['detail'],
                old_record_dict['describe'],
                old_record_dict['from'],
                old_record_dict['to'])
        else:
            print("未知的动账操作!!")
            return False
        # print(record_path)

        e_action = e_date.find(action_path)
        e_record = e_action.find(record_path)
        if e_record is None:
            print("未找到待删除的记录")
            return False
        e_action.remove(e_record)

        if action == 'movement':
            self.modifyBalance(old_record_dict['from'], Decimal(old_record_dict['value']))
            self.modifyBalance(old_record_dict['to'], Decimal(old_record_dict['value']) * (-1))
        else:
            self.reversalVariation(old_record_dict, e_date)
        return True

    def reversalVariation(self, change_dict, e_date):
        """
        Describe: 删除某条记录时,需要冲正原来的记录,将回退对应的存款账户数值变化、以及余额

        Args:
            change_dict: dict
                记录字典
            e_date: Element
                指定日期的day元素
        """
        e_variation = e_date.find(".//variation")
        if e_variation is None:
            print("冲正记录时异常!!该记录不存在余额变化")
            return
        if 'from' in change_dict:
            e_fund_variety = e_variation.find(".//fund[category='{}']/out".format(change_dict['from']))
            if e_fund_variety is None:
                print("冲正记录时异常!!该记录不存在余额变化")
                return
            e_fund_variety.text = str((Decimal(e_fund_variety.text) - Decimal(change_dict['value'])).quantize(Decimal('0.00')))
            self.modifyBalance(change_dict['from'], Decimal(change_dict['value']))

            self.reversalAssociatedFund(e_variation, change_dict, 'from')
        if 'to' in change_dict:
            e_fund_variety = e_variation.find(".//fund[category='{}']/in".format(change_dict['to']))
            if e_fund_variety is None:
                print("冲正记录时异常!!该记录不存在余额变化")
                return
            e_fund_variety.text = str((Decimal(e_fund_variety.text) - Decimal(change_dict['value'])).quantize(Decimal('0.00')))
            self.modifyBalance(change_dict['to'], Decimal(change_dict['value'])*(-1))

            self.reversalAssociatedFund(e_variation, change_dict, 'to')

    def reversalAssociatedFund(self, e_variation, change_dict, from_or_to):
        """
        Describe: 冲正关联账户

        Args:
            e_variation: Element
            change_dict: dict
            from_or_to: ['from', 'to']
        """
        # print(change_dict['associatedFund'])
        if 'associatedFund' in change_dict and change_dict['associatedFund'] != 'None':
            print('执行了associatedFund冲正,操作为', from_or_to)
            if e_variation.find(".//fund[category='{}']".format(change_dict['associatedFund'])) is None:
                print("冲正记录时异常!!该记录不存在关联账户余额变化")
                return
            if from_or_to == 'from':
                e_fund_variety = e_variation.find(".//fund[category='{}']/out".format(change_dict['associatedFund']))
                flag = 1
            elif from_or_to == 'to':
                e_fund_variety = e_variation.find(".//fund[category='{}']/in".format(change_dict['associatedFund']))
                flag = -1
            else:
                print('未知的收支动作!')
                return
            e_fund_variety.text = str((Decimal(e_fund_variety.text) - Decimal(change_dict['value'])).quantize(Decimal('0.00')))
            self.modifyBalance(change_dict['associatedFund'], Decimal(change_dict['value'])*flag)

2. 增加更新记录功能

2.1 功能详述

  • 点击更新按钮后,获取对应行的数据组成新记录字典;
  • 同时根据行号获取编辑账本界面的self.file_parse_result属性对应的旧记录字典(每次更新xml文件时,该属性都会同步);
  • 接着用旧字典数据冲正存款账户余额(实现思路为新增记录时的反向操作),再用新字典数据更新账户余额,>- 最后再更新self.file_parse_result属性。

2.2 代码实现

    def updateTableRow(self, triggeredBtn, tableWidget):
        print("触发了新增按钮")
        # 获取触发信号的控件所在行号
        current_row = tableWidget.indexAt(triggeredBtn.parent().pos()).row()
        if tableWidget == self.tableWidget_expense:
            const_class = expenseConst
            action = 'expense'
        elif tableWidget == self.tableWidget_income:
            const_class = incomeConst
            action = 'income'
        elif tableWidget == self.tableWidget_movement:
            const_class = movementConst
            action = 'movement'
        else:
            print('未知控件触发新增按钮!')
            return
        # 获取被更新的旧数据(文件解析后,记录顺序与表格顺序相同)
        old_data_dict = self.file_parse_result[action+'s'][current_row]
        print("旧记录内容为: \n", old_data_dict)
        # 获取更新后的新数据
        new_data_dict = self.getExistTableCell(tableWidget, current_row, const_class)
        if new_data_dict is None:
            print("获取更新后的数据失败!!")
            return
        print("更新后的记录内容为: \n", new_data_dict)

        if self.file_processor.updateRecord(old_data_dict, new_data_dict, self.dateEdit.text().replace('/', ''), action):
            print("更新成功!")
            # 把删除结果写入文件
            self.file_processor.writeXMLFile(self.lineEdit_file_path.text())

            # 更新self.file_parse_result
            self.file_parse_result[action+'s'][current_row] = new_data_dict
            # print(self.file_parse_result)

其中处理xml文件的方法代码如下:

    def updateRecord(self, old_record_dict, new_record_dict, date_str, action):
        e_date = self.getSpecificDateElement(date_str)
        if isinstance(e_date, int):
            print("未找到这一天的数据!")
            return False

        if action == 'expense':
            action_path = ".//expenses"
            record_path = """.//expense[@necessity='{}'][@associatedFund='{}'][value='{}'][category='{}'][detail='{}'][describe='{}'][from='{}']""".format(
                old_record_dict['necessity'],
                old_record_dict['associatedFund'],
                old_record_dict['value'],
                old_record_dict['category'],
                old_record_dict['detail'],
                old_record_dict['describe'],
                old_record_dict['from'])
        elif action == 'income':
            action_path = ".//incomes"
            record_path = """.//income[@associatedFund='{}'][value='{}'][category='{}'][detail='{}'][describe='{}'][to='{}']""".format(
                old_record_dict['associatedFund'],
                old_record_dict['value'],
                old_record_dict['category'],
                old_record_dict['detail'],
                old_record_dict['describe'],
                old_record_dict['to'])
        elif action == 'movement':
            action_path = ".//movements"
            record_path = """.//movement[value='{}'][detail='{}'][describe='{}'][from='{}'][to='{}']""".format(
                old_record_dict['value'],
                old_record_dict['detail'],
                old_record_dict['describe'],
                old_record_dict['from'],
                old_record_dict['to'])
        else:
            print("未知的动账操作!!")
            return False
        # print(record_path)

        e_action = e_date.find(action_path)
        e_record = e_action.find(record_path)
        if e_record is None:
            print("未找到待删除的记录")
            return False

        # 修改了数值则需要冲正
        if old_record_dict['value'] != new_record_dict['value']:
            # 先冲正原记录数据
            # 在用新数据修改账户变化和余额
            if action == 'movement':
                self.modifyBalance(old_record_dict['from'], Decimal(old_record_dict['value']))
                self.modifyBalance(old_record_dict['to'], Decimal(old_record_dict['value']) * (-1))
                self.modifyBalance(new_record_dict['from'], Decimal(new_record_dict['value']) * (-1))
                self.modifyBalance(new_record_dict['to'], Decimal(new_record_dict['value']))
            else:
                self.reversalVariation(old_record_dict, e_date)
                self.organizeVariation(new_record_dict, e_date)

        # 修改记录数据

        for key in new_record_dict.keys():
            if key == 'necessity':
                e_record.attrib['necessity'] = new_record_dict['necessity']
            elif key == 'associatedFund':
                e_record.attrib['associatedFund'] = new_record_dict['associatedFund']
            else:
                e_record.find(".//"+key).text = str(new_record_dict[key])
        return True

3. 优化界面控件(内置spinBox、增加按钮切换日期)

3.1 功能详述

将记录表格数值(value)列内置QSpinBox,以避免存于文件的数值小数点位不一致;增加按钮来控制日期的切换

3.2 效果展示

【日常收支账本】【Day05】编辑账本界面增加删除、更新记录功能——提高代码复用性
数值(value)列内置QSpinBox
【日常收支账本】【Day05】编辑账本界面增加删除、更新记录功能——提高代码复用性
增加按钮来控制日期的切换

3.3 代码实现

# 内置QDoubleSpinBox
spinBox = QDoubleSpinBox(decimals=2)# 设置保留小数后2位
# 设置范围,默认为[0.0, 100.0)。必须在调整数值前设置,否则大于等于100.0时会变成99.99
spinBox.setRange(0.0, 100000000.0)
spinBox.setSingleStep(0.1)          # 设置步长
spinBox.setValue(value)             # 调整数值
tableWidget.setCellWidget(current_row, keys_list.index(key), spinBox)

# 日期切换
# 利用QDate类的addDays(int)方法
self.pushButton_prev_day.clicked.connect(lambda: self.dateEdit.setDate(self.dateEdit.date().addDays(-1)))
self.pushButton_post_day.clicked.connect(lambda: self.dateEdit.setDate(self.dateEdit.date().addDays(1)))

三、开发总结

1. 提高代码复用性

最近几篇都没有技术含量,就不总结了。唯一值得一提的就是提高代码复用性。文章来源地址https://www.toymoban.com/news/detail-711613.html

  • 对于支出、收入、转移三种动账类型,字段大量重复,于是创建表格时,将所有列的初始化集中到一个函数中,根据列名执行对应初始化方式。
  • 通过设置ExpenseConst、IncomeConst、MovementConst三个具有同名常量的类,更好地支持代码复用
  • 第二章删除和新增记录时修改xml文件的方法deleteRecord(old_record_dict, date_str, action)updateRecord(self, old_record_dict, new_record_dict, date_str, action)是通过action区分动账类型,避免同一个功能需要实现三个方法

到了这里,关于【日常收支账本】【Day05】编辑账本界面增加删除、更新记录功能——提高代码复用性的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动态规划Day16(编辑距离,删除元素待写完)

    目录 583. 两个字符串的删除操作 看到题目的第一想法                看到代码随想录之后的想法 自己实现过程中遇到的困难(看代码) 72. 编辑距离 看到题目的第一想法                看到代码随想录之后的想法 自己实现过程中遇到的困难(看代码) 力扣题目链接(opens new

    2024年01月24日
    浏览(52)
  • Day56 | 583. 两个字符串的删除操作 | 72. 编辑距离

    583. 两个字符串的删除操作 注意点: 1.当word1[i - 1] 与 word2[j - 1]不相同的时候, 情况一:删word1[i - 1],最少操作次数为dp[i - 1][j] + 1 情况二:删word2[j - 1],最少操作次数为dp[i][j - 1] + 1 情况三:同时删word1[i - 1]和word2[j - 1],操作的最少次数为dp[i - 1][j - 1] + 2 因为 dp[i][j-1]+1 = d

    2024年02月08日
    浏览(44)
  • 第24次修改了可删除可持久保存的前端html备忘录:文本编辑框不再隐藏,又增加了哔哩哔哩搜索和必应搜索

    第24次修改了可删除可持久保存的前端html备忘录:文本编辑框不再隐藏,又增加了哔哩哔哩搜索和必应搜索.

    2024年04月12日
    浏览(48)
  • Mac日常随笔(持续更新)

    目录 日常系列 Mac一些快捷键 批量改文件名 Mac强制关闭程序 开发系列 打开Mac命令行 IDea快捷键 选择性截图 Command + Shift + 4 截取整个屏幕 Command + Shift + 3 录屏 Command + Shift + 5 强制退出 Command + Option+ Esc 不过还是微信截图更为方便,可以编辑图片,直接就是已复制状态。 选中所

    2024年02月22日
    浏览(42)
  • 日常刷题 无代码(长期更新

    1401F 线段树题 我们可以考虑为反转 子树 1579g 可以二分 因为会有负数 所以我会把 开始的位置 为 0-mid 然后dp 459e 边权从小到大加入 没有后效性 直接dp 372b 前缀和 1151e 点=边+连通块 见了两次了 这下记住了 505C 直接dp复杂度不对 我们优化一下 dp[i][j] 表示目前到了i 和d偏移了j的

    2024年02月08日
    浏览(37)
  • [XDOJ]日常作业汇总(不定时更新)

    事先声明 : 1.该文章仅用于个人学习,谢绝未经本人同意和任何用于商业用途的搬运。 2.本人22级学生,学校题库内的题目可能会不定期更改题目要求,请各位参照答案的同学对照好题目要求,切莫直接抄袭。 问题描述 给定一个整数数列,数列中连续相同的最长整数序列算

    2024年02月06日
    浏览(36)
  • C#匿名方法增加、删除委托

    匿名方法给我们带来了方便,那么如何增加删除匿名方法中附加的委托(事件)呢 一般写法: 1 2 3 4 this .Loaded += (sender, e) =       {              //Do something       }; 进化写法: 1 2 3 4 5 6 7 this .Loaded += new   RoutedEventHandler(FormulaAssign_Loaded); void   FormulaAssign_Loaded( objec

    2024年02月11日
    浏览(35)
  • Linux/Ubuntu 的日常升级和安全更新,如何操作?

    我安装的是Ubuntu 20.04.6 LTS的Windows上Linux子系统版本,启动完成后显示:  Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.15.90.4-microsoft-standard-WSL2 x86_64)  * Documentation:  https://help.ubuntu.com  * Management:     https://landscape.canonical.com  * Support:        https://ubuntu.com/advantage   System information as of S

    2024年02月12日
    浏览(38)
  • Elasticsearch 常用的增加、删除、修改、查询语句

    新增 删除 修改 批量增删改 查询 查询指定索引下全部数据 查询指定索引下指定id的数据 查询指定索引下全部数据 查询指定值(match) 在多个字段中查询指定值(multi_match) match、multi_match是模糊匹配,匹配时会对所查找的进行分词,然后按分词匹配查找。 term 查询

    2024年02月03日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包