删除在 for 循环中创建的特定帧

Delete a specific Frame which is made in a for loop

提问人:Pavlos Katsioulis 提问时间:5/9/2023 最后编辑:Pavlos Katsioulis 更新时间:5/21/2023 访问量:105

问:

我有复选框,由 for 循环生成。

def MakeMaterialsButtons(self):
        self.ChoosingVariable = ctk.IntVar(value=0)
        CallDB = aoracandlestudiodb.cursor()
        query = 'SELECT idmaterials FROM materials WHERE mat_category = %s '
        CallDB.execute(query, (StickersName,))
        Stickers_Categories_ID3 = CallDB.fetchall()
        i = 1
        j = 1
        mat_distance = 10
        x_mat_distance = 10
        for stickers_item in Stickers_Categories_ID3:
            get_mat_ID_str = str(stickers_item)
            get_mat_ID = get_mat_ID_str[1:-2]
            int(get_mat_ID)
            if mat_distance >= 150:
                x_mat_distance = x_mat_distance + 200
                mat_distance = 10
            self.MakeOrderButtonsForStickers(get_mat_ID, mat_distance, x_mat_distance)
            j = j + 1
            mat_distance = mat_distance + 60



def MakeOrderButtonsForStickers(self, get_mat_ID, mat_distance, x_mat_distance):

    get_mat_name = get_NameOfMaterial(get_mat_ID)
    ItembyCategoryCheckBox = ctk.CTkCheckBox(self.StickersFrame, text=get_mat_name,
                                             command=lambda: self.Add_To_Order_Materials(get_mat_ID, get_mat_name),
                                             fg_color="#a881af", variable=self.ChoosingVariable,
                                             onvalue="1", offvalue="0", width=150, height=40,
                                             text_color='black', font=("arial bold", 20),
                                             border_width=4,
                                             border_color='black')
    ItembyCategoryCheckBox.place(x=x_mat_distance, y=mat_distance)

这是我检查它时的功能。

def Add_To_Order_Materials(self, Mat_ID, mat_name):
    print(self.ChoosingVariable.get())
    Mat_Price = get_PriceOfMaterial(Mat_ID)
    if self.ChoosingVariable.get() == 1:
        if mat_name != self.Name_Order_Counter:
            self.Item_Order_Counter = 1
            self.Item_Order_Distance = self.Item_Order_Distance + 30
            self.Name_Order_Counter = mat_name
            self.Material_Order_Text = ctk.CTkLabel(self.ordertotalframe, text=mat_name, font=("arial bold", 20),
                                                text_color='black')
            self.Material_Order_Text.place(x=55, y=self.Item_Order_Distance)
            self.Material_quantity_text = ctk.CTkLabel(self.ordertotalframe, text=(str(self.Item_Order_Counter) + "x"),
                                                   font=("arial bold", 20), text_color='black')
            self.Material_quantity_text.place(x=210, y=self.Item_Order_Distance)
            self.Material_price_text = ctk.CTkLabel(self.ordertotalframe, text=(str(Mat_Price) + " €"),
                                                font=("arial bold", 20), text_color='black')
            self.Material_price_text.place(x=300, y=self.Item_Order_Distance)
            self.Item_Order_Counter = self.Item_Order_Counter + 1
            self.Order_Total_price = self.Order_Total_price + Mat_Price
            self.Order_Total_price_Label.configure(text=(str(self.Order_Total_price) + " €"))
            self.Material_Order_Text.place()

        else:
            self.Material_quantity_text.configure(text=(str(self.Item_Order_Counter) + "x"))
            self.Material_Order_Text.configure(text=mat_name)
            self.Item_Order_Counter = self.Item_Order_Counter + 1
            self.Order_Total_price = self.Order_Total_price + Mat_Price
            self.Order_Total_price_Label.configure(text=(str(self.Order_Total_price) + " €"))
    else:
        self.Name_Order_Counter = ""
        self.Material_Order_Text.place_forget()
        self.Material_quantity_text.place_forget()
        self.Material_price_text.place_forget()
        self.Item_Order_Distance = self.Item_Order_Distance - 30
        self.Order_Total_price = self.Order_Total_price - Mat_Price
        self.Order_Total_price_Label.configure(text=(str(round(self.Order_Total_price, 2)) + " €"))

因此,它基本上是将材料价格添加到框架上,从而获得订单的总数。 如果我选中了两个我想要的选项,然后我想删除我选中的第一个选项,它只是做这些行

            self.Item_Order_Distance = self.Item_Order_Distance - 30
            self.Order_Total_price = self.Order_Total_price - Mat_Price
            self.Order_Total_price_Label.configure(text=(str(round(self.Order_Total_price, 2)) + "

它不会删除前一个选项,而只会删除我检查的最后一个选项。 有什么想法吗?我是否必须添加一个表格并用它做一些事情,在每个按钮上?我该怎么做

python for-loop tkinter 删除运算符

评论

1赞 Barmar 5/9/2023
循环在哪里?for
0赞 Pavlos Katsioulis 5/9/2023
@barmar我确实添加了for循环
0赞 Barmar 5/9/2023
为什么取消选中选项时要清除?self.Name_Order_Counter
0赞 Barmar 5/9/2023
我不确定这些代码的大部分在做什么。但是,当您单击复选框时,您所要做的就是根据是否选中总价来添加或减去总价。Mat_price
0赞 Pavlos Katsioulis 5/9/2023
好吧self.name_order_counter什么都没做,我只是看到了哈哈

答:

0赞 sawyermclane 5/9/2023 #1

在函数中返回贴纸,如下所示:MakeOrderButtonsForStickers

def MakeOrderButtonsForStickers(self, get_mat_ID, mat_distance, x_mat_distance):

    get_mat_name = get_NameOfMaterial(get_mat_ID)
    ItembyCategoryCheckBox = ctk.CTkCheckBox(self.StickersFrame, text=get_mat_name,
                                             command=lambda: self.Add_To_Order_Materials(get_mat_ID, get_mat_name),
                                             fg_color="#a881af", variable=self.ChoosingVariable,
                                             onvalue="1", offvalue="0", width=150, height=40,
                                             text_color='black', font=("arial bold", 20),
                                             border_width=4,
                                             border_color='black')
    ItembyCategoryCheckBox.place(x=x_mat_distance, y=mat_distance)
    return ItembyCategoryCheckBox

然后,您可以创建类的成员变量,例如 ,并使用 在 for 循环中按索引赋值。sticker_checkboxesenumerate

        ...
        for idx, stickers_item in enumerate(Stickers_Categories_ID3):
            get_mat_ID_str = str(stickers_item)
            get_mat_ID = get_mat_ID_str[1:-2]
            int(get_mat_ID)
            if mat_distance >= 150:
                x_mat_distance = x_mat_distance + 200
                mat_distance = 10
            
            self.sticker_checkboxes[idx] = self.MakeOrderButtonsForStickers(get_mat_ID, mat_distance, x_mat_distance)
            j = j + 1
            mat_distance = mat_distance + 60

现在,您有了一个复选框列表,按创建它们的顺序排列。您也可以将其作为字典,并索引 ,由您决定。sticker_checkboxesget_mat_ID

0赞 acw1668 5/10/2023 #2

由于您已经对所有选中的项目使用了同一组实例变量 (, 和 ),因此它们将引用最后一个选中的项目。self.Material_Order_Textself.Material_quantity_textself.Material_price_text

我建议使用字典来存储那些以Mat_ID为键创建的标签,然后您可以使用Mat_ID轻松访问它们。

以下是修改后的:Add_To_Order_Materials()

def Add_To_Order_Materials(self, Mat_ID, mat_name):
    print(self.ChoosingVariable.get())
    Mat_Price = get_PriceOfMaterial(Mat_ID)
    if self.ChoosingVariable.get() == 1:
        if mat_name != self.Name_Order_Counter:
            self.Item_Order_Counter = 1
            self.Item_Order_Distance = self.Item_Order_Distance + 30
            self.Name_Order_Counter = mat_name
            self.Material_Order_Text = ctk.CTkLabel(self.ordertotalframe, text=mat_name, font=("arial bold", 20),
                                                text_color='black')
            self.Material_Order_Text.place(x=55, y=self.Item_Order_Distance)
            self.Material_quantity_text = ctk.CTkLabel(self.ordertotalframe, text=(str(self.Item_Order_Counter) + "x"),
                                                   font=("arial bold", 20), text_color='black')
            self.Material_quantity_text.place(x=210, y=self.Item_Order_Distance)
            self.Material_price_text = ctk.CTkLabel(self.ordertotalframe, text=(str(Mat_Price) + " €"),
                                                font=("arial bold", 20), text_color='black')
            self.Material_price_text.place(x=300, y=self.Item_Order_Distance)
            self.Item_Order_Counter = self.Item_Order_Counter + 1
            self.Order_Total_price = self.Order_Total_price + Mat_Price
            self.Order_Total_price_Label.configure(text=(str(self.Order_Total_price) + " €"))
            self.Material_Order_Text.place()

            # ************************************************************ 
            # use a dictionary self.order_item_labels to store the labels
            # note that self.order_item_labels should be initialized
            #   elsewhere, for example inside __init__()
            self.order_item_labels[Mat_ID] = (self.Material_Order_Text, self.Material_quantity_text, self.Material_price_text)

        else:
            self.Material_quantity_text.configure(text=(str(self.Item_Order_Counter) + "x"))
            self.Material_Order_Text.configure(text=mat_name)
            self.Item_Order_Counter = self.Item_Order_Counter + 1
            self.Order_Total_price = self.Order_Total_price + Mat_Price
            self.Order_Total_price_Label.configure(text=(str(self.Order_Total_price) + " €"))
    else:
        self.Name_Order_Counter = ""
        # clear removed order item
        for lbl in self.order_item_labels[Mat_ID]:
            lbl.place_forget()
        # remove the item from order list
        self.order_item_labels.pop(Mat_ID, None)
        # populate order list
        for i, labels in enumerate(self.order_item_labels.values(), 1):
            y = i * 30
            labels[0].place(x=55, y=y)
            labels[1].place(x=210, y=y)
            labels[2].place(x=300, y=y)

        self.Item_Order_Distance = self.Item_Order_Distance - 30
        self.Order_Total_price = self.Order_Total_price - Mat_Price
        self.Order_Total_price_Label.configure(text=(str(round(self.Order_Total_price, 2)) + " €"))

评论

0赞 Pavlos Katsioulis 5/21/2023
正如你所看到的,我对此很陌生。我知道字典是如何工作的,但我并不习惯如何使用它。我几乎复制并粘贴了你看到我的内容,唯一的区别是字典的名称,我在课程开始时初始化了它。我收到一个错误,即“...,第 718 行,在 Add_To_Order_Materials 中为 self.order_material_labels[str(Mat_ID)]中的 lbl:文件”...“,第 1681 行,在 cget 中返回 self.tk.call(self._w, 'cget', '-' + key) TypeError: 只能将 str(不是”int“)连接到 str”
0赞 acw1668 5/21/2023
我不明白为什么你得到这个错误,因为你曾经将键转换为字符串,但错误抱怨它是一个整数。str(Mat_ID)
0赞 Pavlos Katsioulis 5/21/2023
我也没有!到最后,我决定总价不需要受材料的影响,也不应该显示材料的价格。我只是想要它们的成本,现在它不是那么复杂。我会按照你向我展示的方式再试一次,我认为这是最好的解决方案,并且由于你解释我的方式,我更容易理解它。无论如何谢谢你!