【问题标题】:What’s the best way to make adaptable tkinter button lists in python?在 python 中制作自适应 tkinter 按钮列表的最佳方法是什么?
【发布时间】:2021-01-09 20:22:58
【问题描述】:

我正在尝试制作一个计算器应用程序,将记忆的数字或方程式存储到字符串列表中。我还尝试创建一个辅助窗口,显示删除按钮和每个内存条目的标签。我正在为它们使用按钮列表和标签列表,并且我正在尝试匹配所有 3 个列表的索引。

当按下删除按钮时,我想在所有三个列表中 .pop 相同的索引,并 .destroy() 按下的按钮及其对应的标签。此功能的一个示例是在 Windows 10 计算器应用程序中。但是,我知道如果我弹出一个索引,它之后的索引就会变成那个索引,所以你不能只为每个按钮分配一个固定的索引。所以我想主要问题是,如何获取特定按钮的当前索引并使用它来确定在其他 2 个列表中删除哪个字符串和标签?我尝试在 memDeleteButtons.index(self) 中使用 self,但由于某种原因它无法解决任何问题。

下面是我正在处理的代码:

def memDestroyer(index):
    
    if memBank.__len__() and memDeleteButtons.__len__() and memLabels.__len__() > 0:   
            memLabels[index].destroy()
            memDeleteButtons[index].destroy()

            memLabels.pop(index)
            memBank.pop(index)
            memDeleteButtons.pop(index)                   
    else:
        return    

def memMenu():
    print(memBank)
    global root1
    root1 = Tk()
    root1.title("Saved Equations")
    root1.geometry("300x600")
        
    index = 0
    for i  in memBank:
        print("loop began")  
        if i == "":
            memBank.pop(memBank.index(i)) 
            continue
        elif index >= memBank.__len__():
            break
        else:
            memLabels.append(Label(root1, text=i))
            memLabels[-1].pack()
            memDeleteButtons.append(Button(root1, text="x"))
            memDeleteButtons[-1].config(command=lambda:memDestroyer(memDeleteButtons.index(self)))
            memDeleteButtons[-1].pack() 
        
        index += 1
        print("loop ended")
            
    root1.mainloop()

【问题讨论】:

  • 您可以使用按钮、标签和字符串存储元组列表。
  • 非常感谢!所以对于按钮,它将是一个元组列表,每个元组都包含按钮和字符串形式的按钮对象 id。使用语法 memDeleteButtons.index((button, objectID)) 检查对象 ID 的位置是否正确?我会做一个测试。

标签: python list tkinter calculator


【解决方案1】:

好的,所以我想出了如何使按钮具有适应性。我需要做两件事:

  1. 弹出索引后,我需要将索引重新分配给按钮上的命令属性。所以我首先创建了一个循环遍历按钮列表并从 0 开始将索引重新分配给它们的命令属性。这确保了所有按钮始终具有更新的命令属性,就像以前一样,它们总是试图引用一个不再属于它们的索引,如果它们之前的索引被弹出。

  2. 我需要在每个按钮的命令属性中用 lambda 编写一个参数。命令是 lambda c=i: memDestroyer(c)。这是因为在循环结束后 i 将始终等于列表的最后一个索引,因此您可以看到这将是一个问题。但是,通过使用 c = 1,c 不是 i,它保存了 i 在特定迭代中曾经等于的值,因此它允许每个按钮都有自己的索引分配。

现在是代码:

def memDestroyer(index):

if memBank.__len__() and memDeleteButtons.__len__() and memLabels.__len__() > 0:   
        print(f"index is {index}")
        memLabels[index].destroy()
        memDeleteButtons[index][0].destroy()
        memLabels.pop(index)
        memBank.pop(index)
        memDeleteButtons.pop(index)
        
        step = 0
        for i in memDeleteButtons:
            print(f"Pointer index is {step}")
            i[0].config(command=lambda c = step: memDestroyer(c))
            step += 1
            
    
else:
    return
    
def memMenu():
    print(memBank)
    global root1
    root1 = Tk()
    root1.title("Saved Equations")
    root1.geometry("300x600")
    
    
    index = 0
    row_index = 1
    for i, v  in enumerate(memBank):
        print("loop began")  
        if v == "":
            memBank.pop(i) 
            continue
        elif i >= memBank.__len__():
            break
        
        else:
            
            
            global button
            
            if memDeleteButtons.__len__() - 1 and memLabels.__len__() - 1 >= i:
                memDeleteButtons.pop(i)
                memLabels.pop(i)
            memLabels.insert(i, Label(root1, text=v))
            memLabels[i].grid(row=row_index, column=2)
            memDeleteButtons.insert(i, [Button(root1, text="x", command=lambda c = i:memDestroyer(i))])
            memDeleteButtons[i][0].grid(row=row_index, column=1) 
           
            # import logging
            # open("Calculator.txt")
           
        index += 1
        row_index += 1
        print(i)
    root1.mainloop()
    return

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 2020-01-16
    • 2013-08-21
    • 2010-09-16
    • 2016-03-24
    • 2021-06-03
    • 1970-01-01
    相关资源
    最近更新 更多