【问题标题】:How to change a list depending on tkinter checkbutton如何根据 tkinter 检查按钮更改列表
【发布时间】:2021-02-08 01:03:37
【问题描述】:

我一直在尝试使用 tkinter CheckButton 小部件来编辑列表中的项目 - 列表中的每个项目都是一个新的检查按钮。我想要一个保存方法来将数据保存到文本文件中,以及一个加载方法来从文本文件中加载信息并根据列表中的项目标记复选框。

到目前为止,这是我的代码,但是当我检查按钮并更新列表/文件时,列表似乎没有改变

这是我的代码,我需要知道为什么当我选中这些框时列表没有更新:

import tkinter.messagebox as box

modulesMain = Tk()
moduleChecks = []

def SaveChanges():
    # Clear the text file
    modules = open("modules.txt", "w") #Write mode to overwrite the whole file
    modules.write("") # Put in blank text
    modules.close()
    modules = open("modules.txt", "a") # Append mode to append the file
    for item in moduleChecks:
        modules.write(item + "\n")
    print(moduleChecks)



appButton = Checkbutton(modulesMain, text = "Test", variable = moduleChecks[0]).grid()
searchButton = Checkbutton(modulesMain, text = "Test", variable = moduleChecks[1]).grid()






Save = Button(modulesMain, text = "Save Changes", command = SaveChanges).grid()

【问题讨论】:

  • edit您的问题并提供可运行的minimal reproducible example
  • 我稍微编辑了一下,但我的主要问题不在代码中,而是在文本的其余部分 - 没有实际错误,只是没有对列表做任何事情

标签: python list tkinter checkbox


【解决方案1】:

这是一个可运行的示例,我认为它展示了如何执行您所询问的所有操作。它假定modules.txt 文件包含以下格式的数据,其中每一行包含一个模块的名称以及是否已检查。

Mod1,0
Mod2,0
Mod3,0

文件中的数据用于创建Checkbuttons 列表(每个模块一个),并最初设置为其当前状态,如文件中所示。

示例代码如下:

from tkinter import *
import tkinter.messagebox as box

dataFilename = "modules.txt"
moduleChecks = []

def ReadModules():
    with open(dataFilename, "r") as file:
        for line in (line.strip() for line in file):
            moduleName, moduleState = line.split(',')
            moduleChecks.append((moduleName, int(moduleState)))
    print('read:', moduleChecks)

def SaveChanges():
    print('writing:', moduleChecks)
    with open(dataFilename, "w") as file:
        for checkButton in moduleCheckbuttons:
            moduleName = checkButton.cget('text')
            moduleState = checkButton.var.get()
            file.write(','.join((moduleName, str(moduleState))) + '\n')

ReadModules()

modulesMain = Tk()
moduleCheckbuttons = []

# Create a Checkbutton for each module based on moduleChecks values.
for moduleName, moduleState in moduleChecks:
    intVar = IntVar(value=moduleState)
    checkButton = Checkbutton(modulesMain, text=moduleName, variable=intVar)
    checkButton.var = intVar  # Attach reference to variable.
    checkButton.grid()
    moduleCheckbuttons.append(checkButton)

saveButton = Button(modulesMain, text="Save Changes", command=SaveChanges)
saveButton.grid()

modulesMain.mainloop()

【讨论】:

  • Mini:这不是回答你的问题吗?
【解决方案2】:

这是一个基本的解决方案。

import tkinter as tk

root = tk.Tk()

#list of options. doubles as checkbox label text
#appending to this list is all that is necessary to create more options
opts = ['App', 'Search']

#create an StringVar for every option
#this way there doesn't have to be type conversions for reading/writing files
vars = [tk.StringVar(value='0') for _ in opts]

#create checkboxes for every option
for opt, var in zip(opts, vars):
    tk.Checkbutton(root, text=opt, variable=var, onvalue='1', offvalue='0').grid(sticky='w')

#write the checkbox values to file
def save_options_state():
    with open("modules.txt", "w") as file:
        file.write(''.join([v.get() for v in vars]))

#set checkbox values from file            
def load_options_state():
    with open("modules.txt", "r") as file:
        for n, var in zip(list(file.read().strip()), vars):
            var.set(n)

#save/load buttons
tk.Button(root, text="save", command=save_options_state).grid()
tk.Button(root, text="load", command=load_options_state).grid(row=2, column=1)

root.mainloop()

【讨论】:

    【解决方案3】:

    每个复选框的变量必须是IntVar。您的 moduleCheck 列表当前未初始化,因此当您尝试访问其中的元素时,您会收到错误消息。

    在下面的代码中(根据你的修改),我初始化了 moduleCheck 以包含两个 IntVar。 当您按下保存按钮时,它会将复选框的当前状态打印到控制台。

    import tkinter as tk
    
    modulesMain = tk.Tk()
    moduleChecks = [tk.IntVar() for i in range(2)]
    
    
    def SaveChanges():
        for idx,item in enumerate(moduleChecks):
            print(f"{idx} = {item.get()}")
    
    appCheck = tk.Checkbutton(modulesMain, text = "App", variable = moduleChecks[0])
    appCheck.grid()
    searchCheck = tk.Checkbutton(modulesMain, text = "Check", variable = moduleChecks[1])
    searchCheck.grid()
    
    saveButton = tk.Button(modulesMain, text = "Save Changes", command = SaveChanges)
    saveButton.grid()
    
    modulesMain.mainloop()
    

    【讨论】:

    • 谢谢。我怎样才能做到这一点,当程序启动时,它从文件中获取信息,并自动选中正确的框(那么如何将项目添加到列表中,以及如何自动选中框
    • @MiniMinnow 这听起来像是另一个问题的主题。
    猜你喜欢
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 2021-07-06
    • 2020-09-07
    • 2023-04-03
    • 2019-07-10
    • 2023-03-13
    • 2021-04-28
    相关资源
    最近更新 更多