简体   繁体   English

如何在 python tkinter 中的动态小部件中应用相同的更改?

[英]How do I apply the same change across dynamic widgets in python tkinter?

I have the following code to create dynamic checkboxes depending on how many rugby players from a certain position have been saved in a database:我有以下代码来创建动态复选框,具体取决于来自某个 position 的橄榄球运动员的数量已保存在数据库中:

#Dynamic Checkboxes
connectDB = sqlite3.connect("H:\\Python\\Uned_5\\Databases\\CDRR.db")
Cursor = connectDB.cursor()
Cursor.execute("SELECT firstName, surname FROM firstTeam WHERE position = 'Prop'")
nameResult = Cursor.fetchall()

for j in range(len(nameResult)):
    theText = nameResult[j]
    propCheckbutton = Checkbutton(framePropCheck, text = theText, bg = theBlue, fg = theWhite, font = ("calibri", 13), state = DISABLED)
    propCheckbutton.grid(row = 0, column = j)

This code is repeated to create dynamic checkboxes for every rugby position.重复此代码以为每个橄榄球 position 创建动态复选框。

When you click a button associated with the player's position, it runs a function that disables all checkboxes apart from the position you click (think of it as a button that filters out player positions).当您单击与播放器的 position 关联的按钮时,它会运行 function 禁用除您单击的 position 之外的所有复选框(将其视为过滤玩家位置的按钮)。 For example if I pressed the "prop" button, all other checkboxes will be disabled apart from the checkboxes containing players who play in the prop position.例如,如果我按下“道具”按钮,除了包含在道具 position 中玩的玩家的复选框之外,所有其他复选框都将被禁用。

This is the code relating to the button:这是与按钮相关的代码:

propButton = Button(framePosition, text = "Props", bg = theGray, fg = theWhite, font = ("calibri", 13), command = selectProps)
propButton.grid(row = 0, column = 0)

And this is the function that it leads to:这是它导致的 function:

def selectProps():    
    try:
        propCheckbutton.config(state = NORMAL)
        hookerCheckbutton.config(state = DISABLED)
        lockCheckbutton.config(state = DISABLED)
        wingerCheckbutton.config(state = DISABLED)
        scrumCheckbutton.config(state = DISABLED)
        flyCheckbutton.config(state = DISABLED)
        centreCheckbutton.config(state = DISABLED)
        fullCheckbutton.config(state = DISABLED)
    except NameError:
        pass

When doing this with only 1 player from every position stored in the database everything works fine, but as soon as a second player is added to the same position as an existing player, the .config only applies to the latest dynamic checkbox.当只使用存储在数据库中的每个 position 中的 1 个播放器执行此操作时,一切正常,但只要将第二个播放器添加到与现有播放器相同的 position 中, .config仅适用于最新的动态复选框。 For example if I had 2 players in the prop position, the first prop would still follow:例如,如果我在道具 position 中有 2 个玩家,第一个道具仍然会跟随:

propCheckbutton = Checkbutton(framePropCheck, text = theText, bg = theBlue, fg = theWhite, font = ("calibri", 13), state = DISABLED)

whereas the second prop would follow:而第二个道具将遵循:

propCheckbutton.config(state = NORMAL)

Is there a way I can make the propCheckbutton.config(state = NORMAL) apply to all dynamic checkboxes?有没有办法让propCheckbutton.config(state = NORMAL)适用于所有动态复选框?

Here is the minimal, reproductible example that should work for others who want to see the issue:这是最小的、可复制的示例,应该适用于希望查看该问题的其他人:

from tkinter import *
import sqlite3
import sys
import os
pathname = os.path.dirname(sys.argv[0])

#This function only applies this propCheckbutton.config to the latest checkbox created 
def selectProps():    
    try:
        propCheckbutton.config(state = NORMAL)
        hookerCheckbutton.config(state = DISABLED)
    except NameError:
        pass

def selectHookers():
    try:
        propCheckbutton.config(state = DISABLED)
        hookerCheckbutton.config(state = NORMAL)
    except NameError:
        pass

#Creating a basic tkinter window
Window = Tk()
Window.geometry("700x700")

#Creating the table in database
connectDB = sqlite3.connect(pathname + "\\CDRR.db")
Cursor = connectDB.cursor()
Cursor.execute(
    """CREATE TABLE IF NOT EXISTS firstTeam(
        firstName text,
        surname text,
        position text
        )""")

#Inserting the data quickly and making sure the same data isn't inserted twice
normalText = str.maketrans("(),'[]",6*" ")
insertValues = ("INSERT INTO firstTeam (firstName, surname, position) VALUES (?, ?, ?)")
selectValues = ("SELECT firstName FROM firstTeam WHERE firstName = ?")
Cursor.execute(selectValues, [("Johnny")])
prop_1 = Cursor.fetchall()
prop_1 = str(prop_1)
prop_1.translate(normalText)
prop_1 = prop_1.strip()
if "Johnny" not in prop_1:
    Cursor.execute(insertValues, [("Johnny"), ("Silverhand"), ("Prop")])
else:
    pass

Cursor.execute(selectValues, [("Jackie")])
prop_2 = Cursor.fetchall()
prop_2 = str(prop_2)
prop_2.translate(normalText)
prop_2 = prop_2.strip()
if "Jackie" not in prop_2:
    Cursor.execute(insertValues, [("Jackie"), ("Welles"), ("Prop")])
else:
    pass

Cursor.execute(selectValues, [("Dexter")])
hooker_1 = Cursor.fetchall()
hooker_1 = str(hooker_1)
hooker_1.translate(normalText)
hooker_1 = hooker_1.strip()
if "Dexter" not in hooker_1:
    Cursor.execute(insertValues, [("Dexter"), ("DeShawn"), ("Hooker")])
else:
    pass

connectDB.commit()

#Buttons
propButton = Button(Window, text = "Props", command = selectProps)
propButton.grid(row = 0, column = 0)

hookerButton = Button(Window, text = "Hookers", command = selectHookers)
hookerButton.grid(row = 0, column = 1)

#Dynamic Checkboxes
Cursor.execute("SELECT firstName, surname FROM firstTeam WHERE position = 'Prop'")
nameResult = Cursor.fetchall()

for j in range(len(nameResult)):
    theText = nameResult[j]
    propCheckbutton = Checkbutton(Window, text = theText, state = DISABLED)
    propCheckbutton.grid(row = 1, column = j)

Cursor.execute("SELECT firstName, surname FROM firstTeam WHERE position = 'Hooker'")
nameResult = Cursor.fetchall()

for j in range(len(nameResult)):
    theRow = 0
    theText = nameResult[j]
    hookerCheckbutton = Checkbutton(Window, text = theText, state = DISABLED)
    hookerCheckbutton.grid(row = 2, column = j)

Window.mainloop()

Thanks for any suggestions.感谢您的任何建议。

You need to use a dictionary to store those Checkbutton widgets group by position , then you can easily enable/disable what you want:您需要使用dictionary来按position存储这些Checkbutton小部件组,然后您可以轻松启用/禁用您想要的:

# enable the checkbuttons with given position
def select_position(position):
    for pos, players in buttons.items():
        for player in players:
            player.config(state=NORMAL if pos == position else DISABLED)

#Buttons
propButton = Button(Window, text="Props", command=lambda: select_position("Prop"))
propButton.grid(row=0, column=0)

hookerButton = Button(Window, text="Hookers", command=lambda: select_position("Hooker"))
hookerButton.grid(row=0, column=1)

buttons = {} # store the checkbuttons group by position

#Dynamic Checkboxes
for i, position in enumerate(["Prop", "Hooker"]):
    Cursor.execute("SELECT firstName, surname FROM firstTeam WHERE position = ?", (position,))
    nameResult = Cursor.fetchall()

    buttons[position] = []
    for j, theText in enumerate(nameResult):
        cb = Checkbutton(Window, text=theText, state=DISABLED)
        cb.grid(row=i+1, column=j)
        buttons[position].append(cb)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM