在通过ElementTree和Tkinter图形用户界面向XML文件中删除和添加元素时,我遇到了一个问题.

这只是一段代码的简化部分,这就是为什么我的命名约定可能看起来有点奇怪,而且我也是相当新手(我是12年级的),尽管如此:

问题是,当在删除一些其他框之后将框(room0的子元素)添加到XML文件中时,它会添加以前从XML文件中删除的所有框,而不是只添加一个框.

我的目标是:

  • 按下添加框按钮时,将框添加到XML文件中的Room 0元素下

  • 将相应的框移至其减号按钮

  • 然后,每次按下添加框按钮(而不是在减go 框后移除所有框)时,可以添加一个框

XML树:(文件名为"asumy.xml"

<data>
    <room0 />
</data>

代码:

import tkinter as tk
from tkinter import *
import xml.etree.ElementTree as ET

root = Tk()
#root dimentions
root.geometry("500x560")
root.title("Box & room organiser")
root.resizable(False,False)
root.configure(background = "#2a2828")
#xml
tree = ET.parse("summary.xml")
xmlroot = tree.getroot()

#function that indents and writes xml file when called
def write_xml(tree):
    ET.indent(tree, space = '\t', level = 0)
    tree.write('summary.xml')

#iterates through the root finding elements of xmlroot
for room0 in xmlroot:
    if room0.tag == 'room0':
        xml_room0 = room0

#counter variable for amount of boxes in xml file        
box_count = 0

def add_box():
    global box_count
    box_count = box_count + 1

    #if box count is 1 add box 1
    if box_count == 1:

        # adding room0's box 1 to the xml file
        for room0 in xmlroot.findall('room0'):
            box1=ET.Element('box1')
            room0.append(box1)

        #alternative way of adding-->
        # xml_room0_box1 = ET.SubElement(xml_room0, "box1")

        write_xml(tree)
        print('box1 added')

    elif box_count == 2:
        #adding room0's box 2 to the xml file
        for room0 in xmlroot.findall('room0'):
            box2=ET.Element('box2')
            room0.append(box2)
        # xml_room0_box2 = ET.SubElement(xml_room0, "box2")
        write_xml(tree)
        print('box2 added')

    elif box_count == 3:
        #adding room0's box 3 to the xml file
        for room0 in xmlroot.findall('room0'):
            box3=ET.Element('box3')
            room0.append(box3)
        # xml_room0_box3 = ET.SubElement(xml_room0, "box3")

        write_xml(tree)
        print('box3 added')

    elif box_count == 4:
        #adding room0's box 4 to the xml file
        for room0 in xmlroot.findall('room0'):
            box4=ET.Element('box4')
            room0.append(box4)
        # xml_room0_box4 = ET.SubElement(xml_room0, "box4")

        write_xml(tree)
        print('box4 added')

    elif box_count == 5:
        #adding room0's box 5 to the xml file
        for room0 in xmlroot.findall('room0'):
            box5=ET.Element('box5')
            room0.append(box5)
        # xml_room0_box5 = ET.SubElement(xml_room0, "box5")

        write_xml(tree)
        print('box5 added')

    elif box_count == 6:
        #adding room0's box 6 to the xml file
        for room0 in xmlroot.findall('room0'):
            box6=ET.Element('box6')
            room0.append(box6)
        # xml_room0_box6 = ET.SubElement(xml_room0, "box6")
        write_xml(tree)
        print('box6 added')

add_box_button = Button(root, text = "+", command = add_box)
add_box_button.pack()

        #alternative minus code using etree
        # from lxml import etree (add at top if using alternative)
        # for elem in parse_tree.findall('//box1'): #findall or xpath (no difference)
        #     parent = elem.getparent()
        #     parent.remove(elem)
        # print(etree.tostring(parse_tree))
        # parse_tree.write('summary.xml')
    
def minus_box1():
#removes box1 element from xml file
    global box_count
    box_count = box_count - 1

    tree =ET.parse('summary.xml')
    xml_root = tree.getroot()

    for room0 in xml_root:
        if room0.tag == 'room0':
            for box1 in room0:
                if box1.tag == 'box1':
                    room0.remove(box1)
    write_xml(tree)
    print('box1 minused')
    
def minus_box2():
    global box_count
    box_count = box_count - 1
    #removes box1 element from summary.xml
    tree=ET.parse('summary.xml')
    xmlroot = tree.getroot()

    for room0 in xmlroot:
        if room0.tag == 'room0':
            for box2 in room0:
                if box2.tag == 'box2':
                    room0.remove(box2)
    write_xml(tree)
    print('box2 minused')

def minus_box3():
    global box_count
    box_count = box_count - 1
    #removes box1 element from summary.xml
    tree=ET.parse('summary.xml')
    xmlroot = tree.getroot()

    for room0 in xmlroot:
        if room0.tag == 'room0':
            for box3 in room0:
                if box3.tag == 'box3':
                    room0.remove(box3)
    write_xml(tree)
    print('box3 minused')

def minus_box4():
    global box_count
    box_count = box_count - 1
    #removes box1 element from summary.xml
    tree=ET.parse('summary.xml')
    xmlroot = tree.getroot()

    for room0 in xmlroot:
        if room0.tag == 'room0':
            for box4 in room0:
                if box4.tag == 'box4':
                    room0.remove(box4)
    write_xml(tree)
    print('box4 minused')

def minus_box5():
    global box_count
    box_count = box_count - 1
    #removes box1 element from summary.xml
    tree=ET.parse('summary.xml')
    xmlroot = tree.getroot()

    for room0 in xmlroot:
        if room0.tag == 'room0':
            for box5 in room0:
                if box5.tag == 'box5':
                    room0.remove(box5)
    write_xml(tree)
    print('box5 minused')

def minus_box6():
    global box_count
    box_count = box_count - 1
    #removes box1 element from summary.xml
    tree=ET.parse('summary.xml')
    xmlroot = tree.getroot()

    for room0 in xmlroot:
        if room0.tag == 'room0':
            for box6 in room0:
                if box6.tag == 'box6':
                    room0.remove(box6)
    write_xml(tree)
    print('box6 minused')

#minus box buttons
room0_box1_minus_button = Button(root, text="-b1", bg = "#2b2828", command = minus_box1)
room0_box1_minus_button.pack()

room0_box2_minus_button = Button(root, text="-b2", bg = "#2b2828", command = minus_box2)
room0_box2_minus_button.pack()

room0_box3_minus_button = Button(root, text="-b3", bg = "#2b2828", command = minus_box3)
room0_box3_minus_button.pack()

room0_box4_minus_button = Button(root, text="-b4", bg = "#2b2828", command = minus_box4)
room0_box4_minus_button.pack()

room0_box5_minus_button = Button(root, text="-b5", bg = "#2b2828", command = minus_box5)
room0_box5_minus_button.pack()

room0_box6_minus_button = Button(root, text="-b6", bg = "#2b2828", command = minus_box6)
room0_box6_minus_button.pack()
root.mainloop()

推荐答案

我要做的第一件事是删除所有这些if语句,无论它们是否导致了问题,它们的效率都不是很高.

我会说,将它们替换为一个函数,该函数将以列表的形式从一个"房间"中获取所有的"盒子".这样,您只需拨打len()(它可以获得列表的长度),并告诉您该房间中所有盒子的编号.

一个简单的函数,类似如下所示

def get_boxes(room):

tree = ET.parse("filename.xml")
root = tree.getroot()
boxList = []

for rooms in root:
    if rooms.tag == room:
        for boxes in rooms:
            boxList.append(boxes.attrib['name'])

return boxList

您还可以删除所有这些全局语句,只要您想知道箱数,只需拨打len(get_boxes(roomName))即可.

同样,您不需要 for each 不同的框删除一个函数,只要您可以获得用户正在 Select 哪个框,简单的删除函数就可以做到这一点,这与以下情况没有什么不同:

def remove_box(boxName, boxRoom):
tree = ET.parse("filename.xml")
root = tree.getroot()

for rooms in root:
    if rooms.tag == boxRoom:
        for boxes in rooms:
            if boxes.attrib['name'] == boxName:
                rooms.remove(boxes)
                break
            
ET.indent(tree, space = '\t', level=0)
tree.write("filename.xml", "utf-8")

添加框的情况也是如此,您几乎可以完全重用一个函数来添加框.传入盒子的名称,它将在哪个房间中,函数可以完成其余的工作

def create_box(boxName, boxRoom):
tree = ET.parse("filename.xml")
root = tree.getroot()

for rooms in root:
    if rooms.tag == boxRoom:
        for boxes in rooms:
            ET.SubElement(boxes, 'box', name = boxName)
            
ET.indent(tree, space = '\t', level=0)
tree.write("filename.xml", "utf-8")

其他一些建议,我会给那里的房间起自己的名字,

ET.SubElement("parent", 'room', name = "Kitchen")

你可以用room.attrib[‘name’]找到这个名字,你也可以对盒子做同样的事情.这样,你真正需要从用户那里收集的只有两件事:他们 Select 了什么盒子,他们在什么房间里.

恐怕我不能在TKinter端帮助你,我一直更喜欢PySimpleGUI,但如果你可以添加和删除框,那么只需将它们添加到添加和删除函数could中就足够了.

我的代码可能到处都是语法错误,但我希望这能有所帮助.

Python相关问答推荐

从嵌套的yaml创建一个嵌套字符串,后面跟着点

启用/禁用shiny 的自动重新加载

isinstance()在使用dill.dump和dill.load后,对列表中包含的对象失败

如何使用SentenceTransformers创建矢量嵌入?

在Python中计算连续天数

使用__json__的 pyramid 在客户端返回意外格式

如何在一组行中找到循环?

一个telegram 机器人应该发送一个测验如何做?""

当我定义一个继承的类时,我可以避免使用`metaclass=`吗?

操作布尔值的Series时出现索引问题

Polars定制函数返回多列

在MongoDB文档中仅返回数组字段

如何将验证器应用于PYDANC2中的EACHY_ITEM?

用LAKEF划分实木地板AWS Wrangler

为什么这个正则表达式没有捕获最后一次输入?

Pandas 数据框自定义排序功能

Django查询集-排除True值

如何从NumPy数组中提取主频?

matplotlib散点图与NaNs和cmap colored颜色 矩阵

如何从matplotlib中的Splter()中获取 colored颜色 条或图例?