在用户单击按钮后创建新字段时如何分配绑定函数?
How do I assign bind functions when new fields are created after user clicks a button?
我有一个表单,用户可以通过单击按钮创建产品属性记录。单击后,四个组合框、一个标签和一个输入字段将加载到构成一条记录的表单上。
第 4 个组合框中的下拉列表取决于前 3 个组合框中的条目。最终用户可能会在输入之前多次单击 "Add" 按钮。我如何确保当用户在单击添加按钮 "N" 次后返回到第一条记录并对第一条记录的组合框进行更改时,适当的值会加载到第四个组合框中?
这是我的
def addItemInEdit():
global rowNum2
global brandDropdownList2, typeDropdownList2, sizeDropdownList2, qtyTextList2, itemList2,
packedDateDropdownList2
####################### Loading label, dropdowns, and text fields
itemList2.append(ttk.Label(frameEdit, text=str(rowNum2 + 1) + ". ").grid(row=rowNum2, column=0))
brandDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOfBrands, width=10))
brandDropdownList2[-1].grid(row=rowNum2, column=1, pady=5, padx=5)
brandDropdownList2[-1].current(0)
typeDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOftypes, width=5))
typeDropdownList2[-1].grid(row=rowNum2, column=2)
typeDropdownList2[-1].current(0)
sizeDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOfSizes, width=10))
sizeDropdownList2[-1].grid(row=rowNum2, column=3, pady=5, padx=5)
sizeDropdownList2[-1].current(0)
packedDateDropdownList2.append(ttk.Combobox(frameEdit, state='disabled', width=7))
packedDateDropdownList2[-1].grid(row=rowNum2, column=4, pady=5)
qtyTextList2.append(ttk.Entry(frameEdit, width=7))
qtyTextList2[-1].grid(row=rowNum2, column=5, padx=5)
qtyTextList2[-1].insert(0, "Qty")
####################### Adding bind functions.
for item in range(len(brandDropdownList2)):
def getDates(event):
listOfDates=[]
################################## Making sure the use has made actual selections
if brandDropdownList2[len(brandDropdownList2)-1].get()!="Brand" and typeDropdownList2[len(brandDropdownList2)-1].get()!="Type" and sizeDropdownList2[len(brandDropdownList2)-1].get()!="Size":
packedDateDropdownList2[len(brandDropdownList2) - 1].config(state='readonly')
packedDateDropdownList[len(brandDropdownList) - 1].set('')
getDatesQuery = "SELECT [PackedOn] FROM SalesData where [Brand]=? AND [Type] = ? AND [Size]=?"
conForDates = pyodbc.connect(dbPath)
curForDates = conForDates.cursor()
dateListOutput = curForDates.execute(getDatesQuery,(brandDropdownList2[len(brandDropdownList2)-1].get(),typeDropdownList2[len(brandDropdownList2)-1].get(),sizeDropdownList2[len(brandDropdownList2)-1].get())).fetchall()
for item in dateListOutput:
if item[0] not in listOfDates:
listOfDates.append(item[0])
packedDateDropdownList2[len(brandDropdownList2)-1].config(values=listOfDates)
else:
packedDateDropdownList2[len(brandDropdownList2) - 1].set('')
packedDateDropdownList2[len(brandDropdownList2) - 1].config(state='disabled')
brandDropdownList2[len(brandDropdownList)-1].bind("<<ComboboxSelected>>",getDates)
typeDropdownList2[len(brandDropdownList)-1].bind("<<ComboboxSelected>>",getDates)
sizeDropdownList2[len(brandDropdownList)-1].bind("<<ComboboxSelected>>",getDates)
rowNum2 = rowNum2 + 1
我知道绑定的 "For" 循环是错误的,但我觉得 Python 有一个我不知道的功能。
- 您的
getDates()
函数总是从最后一行获取值
不正确的组合框。
- 您只需将函数绑定到新添加的组合框即可。
- 最好将
getDates()
放在 addItemInEdit()
函数之外。
以下是您的代码的修改版本:
def getDates(event):
index = event.widget.row_id
# get the dates from database
# is SELECT DISTINCT supported???
getDatesQuery = "SELECT [PackedOn] FROM SalesData where [Brand] = ? AND [Type] = ? AND [Size] = ?"
conForDates = pyodbc.connect(dbPath)
curForDates = conForDates.cursor()
dateListOutput = curForDates.execute(getDatesQuery,(brandDropdownList2[index].get(), typeDropdownList2[index].get(), sizeDropdownList2[index].get())).fetchall()
# should conForDates.close() be called???
listOfDates = list(set(item[0] for item in dateListOutput))
packedDateDropdownList2[index].config(state='readonly')
packedDateDropdownList2[index].config(values=listOfDates)
packedDateDropdownList2[index].set('')
def addItemInEdit():
global rowNum2
itemList2.append(ttk.Label(frameEdit, text=str(rowNum2 + 1) + ". ").grid(row=rowNum2, column=0))
brandDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOfBrands, width=10))
brandDropdownList2[-1].grid(row=rowNum2, column=1, pady=5, padx=5)
brandDropdownList2[-1].current(0)
brandDropdownList2[-1].row_id = rowNum2 # save the current row number
typeDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOftypes, width=5))
typeDropdownList2[-1].grid(row=rowNum2, column=2)
typeDropdownList2[-1].current(0)
typeDropdownList2[-1].row_id = rowNum2 # save the current row number
sizeDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOfSizes, width=10))
sizeDropdownList2[-1].grid(row=rowNum2, column=3, pady=5, padx=5)
sizeDropdownList2[-1].current(0)
sizeDropdownList2[-1].row_id = rowNum2 # save the current row number
packedDateDropdownList2.append(ttk.Combobox(frameEdit, state='disabled', width=7))
packedDateDropdownList2[-1].grid(row=rowNum2, column=4, pady=5)
packedDateDropdownList2[-1].row_id = rowNum2 # save the current row number
qtyTextList2.append(ttk.Entry(frameEdit, width=7))
qtyTextList2[-1].grid(row=rowNum2, column=5, padx=5)
qtyTextList2[-1].insert(0, "Qty")
qtyTextList2[-1].row_id = rowNum2 # save the current row number
# bind the required callback to newly added comboboxes
brandDropdownList2[-1].bind("<<ComboboxSelected>>", getDates)
typeDropdownList2[-1].bind("<<ComboboxSelected>>", getDates)
sizeDropdownList2[-1].bind("<<ComboboxSelected>>", getDates)
rowNum2 += 1
我有一个表单,用户可以通过单击按钮创建产品属性记录。单击后,四个组合框、一个标签和一个输入字段将加载到构成一条记录的表单上。
第 4 个组合框中的下拉列表取决于前 3 个组合框中的条目。最终用户可能会在输入之前多次单击 "Add" 按钮。我如何确保当用户在单击添加按钮 "N" 次后返回到第一条记录并对第一条记录的组合框进行更改时,适当的值会加载到第四个组合框中?
这是我的
def addItemInEdit():
global rowNum2
global brandDropdownList2, typeDropdownList2, sizeDropdownList2, qtyTextList2, itemList2,
packedDateDropdownList2
####################### Loading label, dropdowns, and text fields
itemList2.append(ttk.Label(frameEdit, text=str(rowNum2 + 1) + ". ").grid(row=rowNum2, column=0))
brandDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOfBrands, width=10))
brandDropdownList2[-1].grid(row=rowNum2, column=1, pady=5, padx=5)
brandDropdownList2[-1].current(0)
typeDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOftypes, width=5))
typeDropdownList2[-1].grid(row=rowNum2, column=2)
typeDropdownList2[-1].current(0)
sizeDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOfSizes, width=10))
sizeDropdownList2[-1].grid(row=rowNum2, column=3, pady=5, padx=5)
sizeDropdownList2[-1].current(0)
packedDateDropdownList2.append(ttk.Combobox(frameEdit, state='disabled', width=7))
packedDateDropdownList2[-1].grid(row=rowNum2, column=4, pady=5)
qtyTextList2.append(ttk.Entry(frameEdit, width=7))
qtyTextList2[-1].grid(row=rowNum2, column=5, padx=5)
qtyTextList2[-1].insert(0, "Qty")
####################### Adding bind functions.
for item in range(len(brandDropdownList2)):
def getDates(event):
listOfDates=[]
################################## Making sure the use has made actual selections
if brandDropdownList2[len(brandDropdownList2)-1].get()!="Brand" and typeDropdownList2[len(brandDropdownList2)-1].get()!="Type" and sizeDropdownList2[len(brandDropdownList2)-1].get()!="Size":
packedDateDropdownList2[len(brandDropdownList2) - 1].config(state='readonly')
packedDateDropdownList[len(brandDropdownList) - 1].set('')
getDatesQuery = "SELECT [PackedOn] FROM SalesData where [Brand]=? AND [Type] = ? AND [Size]=?"
conForDates = pyodbc.connect(dbPath)
curForDates = conForDates.cursor()
dateListOutput = curForDates.execute(getDatesQuery,(brandDropdownList2[len(brandDropdownList2)-1].get(),typeDropdownList2[len(brandDropdownList2)-1].get(),sizeDropdownList2[len(brandDropdownList2)-1].get())).fetchall()
for item in dateListOutput:
if item[0] not in listOfDates:
listOfDates.append(item[0])
packedDateDropdownList2[len(brandDropdownList2)-1].config(values=listOfDates)
else:
packedDateDropdownList2[len(brandDropdownList2) - 1].set('')
packedDateDropdownList2[len(brandDropdownList2) - 1].config(state='disabled')
brandDropdownList2[len(brandDropdownList)-1].bind("<<ComboboxSelected>>",getDates)
typeDropdownList2[len(brandDropdownList)-1].bind("<<ComboboxSelected>>",getDates)
sizeDropdownList2[len(brandDropdownList)-1].bind("<<ComboboxSelected>>",getDates)
rowNum2 = rowNum2 + 1
我知道绑定的 "For" 循环是错误的,但我觉得 Python 有一个我不知道的功能。
- 您的
getDates()
函数总是从最后一行获取值 不正确的组合框。 - 您只需将函数绑定到新添加的组合框即可。
- 最好将
getDates()
放在addItemInEdit()
函数之外。
以下是您的代码的修改版本:
def getDates(event):
index = event.widget.row_id
# get the dates from database
# is SELECT DISTINCT supported???
getDatesQuery = "SELECT [PackedOn] FROM SalesData where [Brand] = ? AND [Type] = ? AND [Size] = ?"
conForDates = pyodbc.connect(dbPath)
curForDates = conForDates.cursor()
dateListOutput = curForDates.execute(getDatesQuery,(brandDropdownList2[index].get(), typeDropdownList2[index].get(), sizeDropdownList2[index].get())).fetchall()
# should conForDates.close() be called???
listOfDates = list(set(item[0] for item in dateListOutput))
packedDateDropdownList2[index].config(state='readonly')
packedDateDropdownList2[index].config(values=listOfDates)
packedDateDropdownList2[index].set('')
def addItemInEdit():
global rowNum2
itemList2.append(ttk.Label(frameEdit, text=str(rowNum2 + 1) + ". ").grid(row=rowNum2, column=0))
brandDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOfBrands, width=10))
brandDropdownList2[-1].grid(row=rowNum2, column=1, pady=5, padx=5)
brandDropdownList2[-1].current(0)
brandDropdownList2[-1].row_id = rowNum2 # save the current row number
typeDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOftypes, width=5))
typeDropdownList2[-1].grid(row=rowNum2, column=2)
typeDropdownList2[-1].current(0)
typeDropdownList2[-1].row_id = rowNum2 # save the current row number
sizeDropdownList2.append(ttk.Combobox(frameEdit, state='readonly', values=listOfSizes, width=10))
sizeDropdownList2[-1].grid(row=rowNum2, column=3, pady=5, padx=5)
sizeDropdownList2[-1].current(0)
sizeDropdownList2[-1].row_id = rowNum2 # save the current row number
packedDateDropdownList2.append(ttk.Combobox(frameEdit, state='disabled', width=7))
packedDateDropdownList2[-1].grid(row=rowNum2, column=4, pady=5)
packedDateDropdownList2[-1].row_id = rowNum2 # save the current row number
qtyTextList2.append(ttk.Entry(frameEdit, width=7))
qtyTextList2[-1].grid(row=rowNum2, column=5, padx=5)
qtyTextList2[-1].insert(0, "Qty")
qtyTextList2[-1].row_id = rowNum2 # save the current row number
# bind the required callback to newly added comboboxes
brandDropdownList2[-1].bind("<<ComboboxSelected>>", getDates)
typeDropdownList2[-1].bind("<<ComboboxSelected>>", getDates)
sizeDropdownList2[-1].bind("<<ComboboxSelected>>", getDates)
rowNum2 += 1