提问人:Pavlos Katsioulis 提问时间:5/9/2023 最后编辑:Pavlos Katsioulis 更新时间:5/21/2023 访问量:105
删除在 for 循环中创建的特定帧
Delete a specific Frame which is made in a for loop
问:
我有复选框,由 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)) + "
它不会删除前一个选项,而只会删除我检查的最后一个选项。 有什么想法吗?我是否必须添加一个表格并用它做一些事情,在每个按钮上?我该怎么做
答:
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_checkboxes
enumerate
...
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_checkboxes
get_mat_ID
0赞
acw1668
5/10/2023
#2
由于您已经对所有选中的项目使用了同一组实例变量 (, 和 ),因此它们将引用最后一个选中的项目。self.Material_Order_Text
self.Material_quantity_text
self.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
我也没有!到最后,我决定总价不需要受材料的影响,也不应该显示材料的价格。我只是想要它们的成本,现在它不是那么复杂。我会按照你向我展示的方式再试一次,我认为这是最好的解决方案,并且由于你解释我的方式,我更容易理解它。无论如何谢谢你!
评论
for
self.Name_Order_Counter
Mat_price