wxFormBuilder + wxPython 工具开发第三章-日记本工具树节点增、改、删功能

article/2025/9/12 8:52:48

目录

前言

一、添加树右击菜单

二、新增

1、实现二级日期节点新增

2、实现三级文章节点新增

三、修改

四、删除


前言

上一章节实现了对目记本表数据设计,数据库连接,数据展示的功能

wxFormBuilder + Python 工具开发第二章-日记本工具数据连接与展示_魂尾ac的博客-CSDN博客

本章节实现对树节点的增、改、删,等功能

文章功能内容

wxF右击菜单添加(wxF是wxFormBuilder缩写)

wxF新增修改对话框添加

新增、修改、删除前端后台逻辑开发

本节最终效果图

一、添加树右击菜单

步骤1、添加菜单项

在wFX里的MaminFrame里添加一个wxMenu菜单,

在其下添加三个wxMenuItem菜单项,新增、修改、删除

每个菜单项都绑定一选择事件函数

步骤2、树右击事件

选中m_nodetree: wxTreeCtrl 在右边Events里找到OnRightDown,绑定一下事件函数on_pop_right_menu

步骤3、更新python代码

将更新的python代码复制到工程代码的noname.py文件里

步骤4、newWindow.py覆盖

将新增的四个响应函数在newWindow.py文件里覆盖掉

并在on_pop_right_menu里添加弹出菜单代码   

 def on_pop_right_menu(self, event):#弹出菜单self.PopupMenu(self.right_click_menu)def On_add_node(self, event):event.Skip()def On_change_node(self, event):event.Skip()def On_del_node(self, event):event.Skip()

        

步骤5、运行

运行runMain.py,打开窗体

在树上右击,打开右击菜单,如下图,展示了新增、修改、删除三个菜单项

将菜单的响应按钮添加打印语句,如下

再次运行,依次点击新增、修改、删除菜单,检查打印结果

好、右击菜单已经完成,下面开始做节点新增功能

二、新增

在新增树节点前呢,笔者发现树表中少了个字段,level,节点等级字段,所以现在给加上

新增一列,命名为level,对应节点的level值都加上,根目录为1,日期为2,文章标题为3

修改后运行程序,不会发生任何改变,level字段仅作后台逻辑判断用。

1、实现二级日期节点新增

它将自动生成当天日期节点,不需要弹框命名。

日期有限制不能与其它二级节点日期相同,一天不能生成两个二级节点

只有选择根节点生成,在选择二、三级节点时,无法新增二级节点,

步骤1、在newWindow.py文件的on_add_node函数里编写通过level字段判断来添加不同类型的节点,代码如下

        验证一下:

选择根目录,右击选择新增菜单,查看打印

选择二级目录,右击选择新增菜单,查看打印

选择三级目录,右击选择新增菜单,查看打印

步骤2、只有选择根节点生成,在选择二、三级节点时,无法新增二级节点,这一点需求完成了,现在开始实现另外两个需求。

它将自动生成当天日期节点,不需要弹框命名。

日期有限制不能与其它二级节点日期相同,一天不能生成两个二级节点

需要用到datatime库,

import datetime

from datetime import datetime

这两种方式引datetime库,个人喜欢第种,第一种使用起来在重要编写两次datetime。

如获取当前时间,datetime.datetime.now()

第二种导入方式只需要写一次: datetime.now()

在newWindow.py文件的NewWindow类中添加add_day_node函数与is_today_in_my_tree函数

add_day_nod来生成当前天日期数据与节点,is_today_in_my_tree是判断日期是否在my_tree里面存在。

代码如下

在On_add_node的level==1判断下调用add_day_node,验证一下,今天还没生成数据的打印

下一步开始编写添加数据与节点代码了,添加节点时不影响当前选择,要做成单节点添加,不要做重新加载树的功能,会显的很low。

要将最新数据重新读取到my_tree里去,防止重复添加二级(日期)节点的BUG

Ps:前面我们有树表中添加level字段,所以新增树节点的sql要跟进添加level字段的写入,在sqliteio.py的insert_treeNode_data函数中

并且添加commit事务提交句话,并将新增成功数据的id返回

插入节点数据

通过insert_treeNode_data方法内的sql语,需要参数data[‘tree_node’: ‘axxx’, ‘parent_id’: 1 , ‘level’: 2],

所以在newWindow.py的add_day_node添加代码

增加树节点

代码编写如下

在调用的地方添加个返回值打印,

运行,选择根目录,右击菜单新增,检查效果如下图。

此时还可以添加二组个相同的日期节点,这是个逻辑BUG

所以我们还得在添加节点后面增加一行重新加载m_tree数据的代码

运行,将重复两条数据都删除掉,再次新增两次,可以看到第一次成功,第二次失败

二级(日期)节点增加完毕,下面开始做三级节点增加了,

2、实现三级文章节点新增

三级目录,是文章的标题,随意命名,所以会弹出对话框,对话框中有编辑框,确认/取消按钮

步骤1、添加对话框

在wxF里面添加对话框,布局,名称编辑框,确认/取消按钮,按照下面的顺序添加,元素与事件须跟进。

  1. 添加对话框元素 Froms----Dialog , name:NewNodeDlg,title:新增文章节点,id:wxID_ADD_NODE size:280;130
  2. 添加布局1 :Loyout----wxBoxSizer,orient:wxVERTICAL(纵向)
  3. 在布局下添加文字编辑框 Common----wxTextCtrl,name:m_nodeName,id:wxID_NODENAME,size:270;30
  4. 在布局下添布局1-1: Loyout----wxBoxSize,orient:wxHORIZONTAL(横向)

5)在布局添加确认按钮:Common----wxButton, name:m_confirm,label: 确认,id:wxID_CONFIRM,size:130;30,响应事件Events函数--OnButtonClick: on_confirm

取消按钮Common----wxButton, name:m_cancel,label: 取消,id:wxID_CANCEL,size:130;30,响应事件Events函数--OnButtonClick: on_cancel

检查生成的代码,一个崭新的类NewNodeDlg

步骤2、弹出对话框

1)新对话框生成一个新的类,在代码目录NodeBook/template下新增newNOdedlg.py文件,将新生成的代码copy进去,版本异常代码修改好

  1. 在NodeBook/manage目录下新增newNode.py文件,其中添加如下代码,继承NewNodeDlg类,按钮的响应函数也覆盖一下
from NodeBook.template.newNodedlg import NewNodeDlgclass NewNode(NewNodeDlg):# Virtual event handlers, overide them in your derived classdef on_confirm(self, event):event.Skip()print('确认')def on_cancel(self, event):event.Skip()print('取消')

  1. 还不能弹出对话框,我们是要将对话框在主窗体中的树上右击新增菜单新增,判断是二级节点后展示。

所以先要将对话框在主窗体中创建一个对象,所以在newWindow.py里导入NewNode类构造函数中加入创建对像语句

from NodeBook.manage.newNode import NewNode

.....

self.andlg = NewNode(self)

再需要在On_add_node函数中的node[‘level’] == 2的判断下添加self.andlg.show()语句

4)好了,此时弹出对话框的代码已经写完,运行runMain.py

选择对二级节点,右击-新增,对话框弹出如下

接下来便可在确认按钮的响应函数中添加相关逻辑了,

步骤3、添加‘修改’菜单兼容代码

在添加前,我们可以确认一个东西,‘修改’菜单也需要用到对话框,一事不凡二主,继续用这个对话框来修改功能

二者都可用一个对话框的前题是在NewNode类中添加一个初始化函数,定义三个参数,

参数一type,用来判断新或修改;

参数二data,用来接收节点数据,一个设置新增与修改类型的函数,

参数三item,传父节点或原节点对象。

在 set_open_data函数里会传入这三种数据

    def __init__(self, parent):super().__init__(parent)#数据self.data = {}#操作类型,0新增/1修改self.type = 0#父节点或源节点self.item = Nonedef set_open_data(self, type, data,item):'''show对话前设置相关数据:param type: 0为新增,1为修改:param data: 新增时,data为父节点数据,:param item: 父节点或源节点对象:return:'''if type == 0:self.SetTitle('新增文章节点')else:self.SetTitle('修改文章节点')self.type = typeself.data = dataself.item = item

然后在NewWindow类中的新增响应函数On_add_node与修改响应函数On_change_node里添加调用set_open_data函数的代码,新增传0, 修改传1

新增: 

 self.andlg.set_open_data(0, data, tree_item)self.andlg.ShowModal()

修改: 

 # 获取当前选择的节点对象tree_item = self.m_nodetree.GetSelection()# 获取当前节点的datadata = self.m_nodetree.GetItemData(tree_item)self.andlg.set_open_data(1, data, tree_item)self.andlg.ShowModal()

PS:这里的Show()函数改ShowModal(),是使对话框模态话,模态话就是对话框不关闭,后面的主框体不可以被点击,类似于浏览器中的蒙板loading

运行,树节点二级目录右击菜单新增

关闭对话框后,再右击菜单修改

        

好,相关与修改菜单兼容的功能已经完成。

步骤4、新增三级文章目录

新增的最后一步操作是,确认,所以在确认按钮的响应函数里添加逻辑

在NewNode类中on_confirm添加逻辑

1)判断是新增还是修改

 2)增加一个add_new_node的函数,在里面添加增加的逻辑:

a、获取 编辑框 的文字

        

编辑的对象是m_nodeName, 编写代码

node_text = self.m_nodeName.GetLineText(0)

b、将获取到的 文字 与 parent_id = data[‘id’] ,level = 3,拼接一个新的节点数据new_data,插入数据,插入成功,再将返回的id更新到new_data中

编写代码

node_text = self.m_nodeName.GetLineText(0)
new_data = {}
new_data['tree_data'] = node_text
new_data['parent_id'] = self.data['id']
new_data['level'] = 3
reslut = sqlt.insert_treeNode_data(new_data)
if reslut is False: return '插入数据失败'
new_data['id'] = reslut[1]

c、将new_data传给newWindow,让其展示出来

先在NewWindow类中添加add_new_node函数,编写代码

 def add_new_node(self, new_data, parent_item):'''在树上添加三级节点:param new_data: 新节点数据:param parent_item: 父节点对象:return:'''self.m_nodetree.AppendItem(parent_item, new_data['tree_node'], data=new_data)

上面代码就将new_data添加到parent_item中去

再在NewNode类中的add_new_node中添加代码

self.GetParent().add_new_node(new_data, self.item)

self.Show(False)

上面第一个框第一行代码是将获取初始化的parent对象,也就是NewWindow的对象,然后调add_new_node函数,传入new_data与父节点item,在树上展示新节点

第二行是隐藏对话框,它的工作已经完成,须要隐藏起来

第二个框是对话框确认按钮里调用自身的add_new_node函数,新增节点

步骤五:运行,测试

在2022-09-15节点下,添加‘湖广两地’

查看结果,‘2022-09-15’节点下多了‘湖广两地’节点

新增功能完成了,接下来便是修改功能了

三、修改

修改的框架代码在新增中已经添加差不了我,只需要在NewNode类中增加一个change_node,用来修改数据与调用NewWindow里的修改节点函数

步骤1、添加修改函数

回忆一下,前面我们实现了,NewWindow类中修改对话框的打开

NewNode类中设置打开数据时,修改的代码,

NewNode类中 确认按钮的响应函数的修改类型判断代码

接下来在NewNode类中添加一个change_node方法,

获取编辑框文字,将文件修改到data[‘tree_node’],然后修改到数据库中,编写代码        

def change_node(self):node_text = self.m_nodeName.GetLineText(0)self.data['tree_node'] = node_textif(sqlt.update_treeNode_data(self.data)) is False:return '更新节点失败'

步骤2、将data修改到节点中

在NewWindows添加change_name函数,在其中编写修改节点文字与数据的代码    

def change_node(self, data, item):'''修改节点:param data: 节点数据修改后:param item: 修改节点对象:return:'''self.m_nodetree.SetItemText(item, data['tree_node'])self.m_nodetree.SetItemData(item, data)

 然后在NewNode的change_node添加修改节点的代码,隐藏对话框的代码

在确认按钮响应函数的修改判断下添加调chanege_node函数的代码

步骤3、运行与测试

选择‘湖广两地’修改变‘三湘四水’

成功展示如下

修改功能编写完成

四、删除

步骤1:添加删除代码

删除,不需要什么代码,在NewWindow类中的删除菜单响应函数On_del_node中添加逻辑代码

1)先获取节点,判断有没有子节点,无可删,有不可删除

2)根节点不可删除

3)删除节点数据,树节点展示移除

步骤2:运行,测试

根目录删除,这里它有子节点,子节点判断在前,所以打印子节点提示

二级目录下有目录删除

三级目录删除

将三级目录全删除,再删除二级目录

再删除根目录

本章完,下一章节编写文章内容的增删改查

全文代码下载地址:

wxFormBuilder+wxPyton日记本小工具(完整版)-Python文档类资源-CSDN下载


http://chatgpt.dhexx.cn/article/gX659jqn.shtml

相关文章

进程和多线程的生命周期

进程和线程 进程 对于操作系统来说,一个任务就是一个进程(Process)。 课本概念:程序的一个执行实例,正在执行的程序等。 内核观点:担当分配系统资源(CPU时间,内存)的实…

Python 线程的生命周期

CPU 在轮换执行线程过程中,线程都经历了什么呢?线程从创建到消亡的整个过程,可能会历经 5 种状态,分别是新建、就绪、运行、阻塞和死亡,如图 1 所示。 图 1 线程状态转换图 线程的新建和就绪状态 无论是通过 Thread …

线程的生命周期和线程池的生命周期

目录 线程的生命周期 1、新建状态 2、就绪状态 3、运行状态 4、死亡状态 5、阻塞状态 线程池的生命周期 1、RUNNING 2、SHUTDOWN 3、STOP 4、TIDYING 5、TERMINATED 线程的生命周期 1、新建状态 通过new关键字创建出一个线程对象,没有启动之前&#xff…

Java多线程的生命周期

多线程的生命周期 1. 线程周期 NEW :新建状态。RUNNABLE:在JAVA虚拟机中执行的线程处于这个阶段BLOCKED:线程阻塞状态,被阻塞等待监视器锁定的线程处于这个状态。WAITING:正在等待另一个线程执行特定的动作的线程处于…

Java多线程(1):线程生命周期

您好,我是湘王,这是我的CSDN博客,欢迎您来,欢迎您再来~ 从事Java开发这些年来,如果要问我Java当中最难的部分是什么?最有意思的部分是什么?最多人讨论的部分是什么?那我会…

多线程的生命周期

1、线程的生命周期及五种基本状态 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t new Thread(); 就绪状态(Runnable):当调用线程对象的start()方法&…

Java线程的生命周期(有代码演示)

文章目录 概览NEWRUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED 概览 Java语言中,多线程是由线程的核心概念驱动的,而线程的生命周期会经历以下的不同状态。 Java java.lang.Thread类包含了一个静态类State,它定义了线程的状态&#xff…

Java 多线程之线程的生命周期 | 图解

转载:https://www.exception.site/java-concurrency/java-concurrency-thread-life-cycle 在 Java 初中级面试中,关于线程的生命周期可以说是常客了。本文就针对这个问题,通过图文并茂的方式详细说说。 结合上图,线程的生命周期大…

java多线程之线程的生命周期

1.生命周期 一个事物从出生的那一刻开始到最终死亡中间的整个过程.在事物的漫长的生命周期过程中,总会经历不同的状态(婴儿状态/青少年状态/中年状态/老年状态...).线程也是有生命周期的,也是存在不同的状态的,状态相互之间的转换. 线程对象的状态存放在Thread类的内部类(Sta…

线程生命周期及五种状态

文章目录 一、线程生命周期及五种状态1、New(初始化状态)2、Runnable(就绪状态)3、Running(运行状态)4、Blocked(阻塞状态)5、Terminated(终止状态) 二、线程基本方法1、线程等待(wait)2、线程睡眠(sleep)3…

线程的生命周期和状态

线程的六种状态 线程的生命周期主要有以下六种状态: New(新创建)Runnable(可运行)Blocked(被阻塞)Waiting(等待)Timed Waiting(计时等待)Termin…

线程的生命周期以及其中的方法

文章目录 线程的生命周期线程的5种状态 线程的基本方法线程等待:wait 方法线程睡眠:sleep 方法线程让步:yield 方法线程中断:interrupt 方法线程加入:join 方法线程唤醒:notify 方法后台守护线程&#xff1…

Java多线程 (五)—— 线程的生命周期

文章目录 前言1、线程生命周期1.1、NEW(新建)1.2、RUNNABLE(可运行)1.3、BLOCKED(阻塞)1.4、WAITING(等待)1.5、TIMED_WAITING(计时等待)1.5、TERMINATED&…

线程的生命周期及五种基本状态

一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程各重要知识点。掌握了上图中的各知识点,Java中的多线程也就基本上掌握了。主要包括: Java线程具有五…

浅谈线程的生命周期

当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)5种状态…

java中,线程的生命周期

java中,线程的生命周期 一、什么是线程? 见之前写的。 当线程启动后(线程对象调用start方法),它不能一直"独占"着CPU独自运行,所以CPU需要在多条线程之间切换,于是线程状态也会多次…

JAVA 多线程并发

1.1.1. JAVA 并发知识库 1.1.2. JAVA 线程实现/创建方式 1.1.2.1. 继承 Thread 类 Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过 Thread 类的 start()实例方法。start()方法是一个 native 方法,它…

攻防世界 web高手进阶区 10分题 TimeKeeper

前言 继续ctf的旅程 开始攻防世界web高手进阶区的10分题 本文是TimeKeeper的writeup 解题过程 进入界面 惯例源码御剑 源码没发现 御剑扫到一个Flask debug console 先正常注册登录 尝试在注册和登录界面sqli 失败 没有别的头绪 就尝试研究debug 参考Flask debug pin安全问…

【Linux时钟系统】

Linux系统时间 时间设备![在这里插入图片描述](https://img-blog.csdnimg.cn/7c50db7d72ba4ff5a0f1264629769184.png)RTC时钟系统计时设备(吴斌个人主页)定时通知设备(吴斌个人主页)系统启动过程中的时钟系统SMP初始化阶段Linux时钟中断低精度定时器的使…

linux时间子系统 - clocksource/timekeeper

linux时间子系统中有一个很重要的记录时间的模块就是timekeeper,而timekeeper需要底层clock硬件设备的支持,每一个设备用结构体clocksource来表示,注册进系统的每一个clocksource会凭借优先级最终被选择成为timekeeper的时钟源。 1. clocksou…