如果有其他讨论已经解决了这个问题,我预先表示歉意,但我找不到任何东西。我是 Python 新手(除了 90 年代的一点点 Pascal 之外,我也是编程新手)。
我正在构建一个带有 tk 输入框的 GUI,供用户输入值,然后将其存储在 sqlite 数据库中。我希望用户能够单击列表框中某一字段的值,然后用所选记录的所有字段的值重新填充 tk 输入框。我已经能够完成这项工作,但它仅在第二次单击时起作用,因为我将列表框绑定到函数以填充 Button-1 上的 tk 输入框。第一次单击会生成以下错误,我在其他问题中看到了引用,但我无法将这些答案转化为我的情况:
Error:
回溯(最近一次调用最后一次):
文件“...\Python\Python38-32\lib\tkinter__init__.py”,第 1883 行,位于call返回 self.func(*args)
文件“fe.py”,第 108 行,在 selectitem 中
所选项目.append(lb1.get(index))
文件“...\Python\Python38-32\lib\tkinter__init__.py”,第 3182 行,在 get 中
返回 self.tk.call(self._w, 'get', 首先)
_tkinter.TclError:错误的列表框索引“”:必须是活动的、锚点、结束、@x、y 或数字
下面是复制错误的示例代码 - 要使用,首先通过填写 VAL 和 REF 框并单击添加项目按钮,通过设置 -> 项目菜单添加几个值。然后单击列表框中的一项。第一次单击应该会生成上述错误。当您第二次单击时,应填充输入框:
```
import sqlite3
import itertools
import tkinter as tk
from tkinter import ttk
INTRO_FONT = ("Arial", 72)
LARGE_FONT = ("Arial", 12)
NORMAL_FONT = ("Arial", 10)
SMALL_FONT = ("Arial", 8)
#Function to create database
def create_db():
conn = sqlite3.connect("demo.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS demotable (id INTEGER PRIMARY KEY, val TEXT, ref TEXT)")
conn.commit()
conn.close()
#Create database
create_db()
#Main Class to manage frames
class demo(tk.Tk):
def __init__(self,*args,**kwargs):
tk.Tk.__init__(self,*args,**kwargs)
container = tk.Frame(self)
container.pack(side="top",fill="both",expand=True)
container.grid_rowconfigure(0,weight=1)
container.grid_columnconfigure(0,weight=1)
menubar = tk.Menu(container)
filemenu = tk.Menu(menubar,tearoff=0)
filemenu.add_command(label="Exit", command=quit)
menubar.add_cascade(label="File", menu=filemenu)
setupmenu = tk.Menu(menubar, tearoff=0)
setupmenu.add_command(label="Items",command = lambda: self.show_frame(Itemsetuppage))
menubar.add_cascade(label="Setup", menu=setupmenu)
tk.Tk.config(self, menu=menubar)
self.frames={}
for F in (Itemsetuppage,Itemsetuppage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Itemsetuppage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
# Frame that inserts and loads values
class Itemsetuppage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
#Function to populate listbox with values
def popitemlist(self):
lb1.delete(0, tk.END)
for item in itemlist():
lb1.insert(tk.END, item)
#Function to add new item to database
def additem():
additem_db(val.get(), ref.get())
val_entry.delete(0, 'end')
ref_entry.delete(0, 'end')
popitemlist(self)
#Function used to populate tk.Entry boxes from database when item in listbox is clicked
def selectitem(event):
global selecteditem
selecteditem = []
ndex = lb1.curselection()
selecteditem.append(lb1.get(ndex))
itemquery = select_item(selecteditem)
val_entry.delete(0, 'end')
val_entry.insert(0, itemquery[1])
ref_entry.delete(0, 'end')
ref_entry.insert(0, itemquery[2])
#Function to query database for values to populate lb1
def itemlist():
conn = sqlite3.connect("demo.db")
cur = conn.cursor()
cur.execute("SELECT DISTINCT val FROM demotable")
results = cur.fetchall()
itemlist = list(itertools.chain(*results))
conn.commit()
conn.close()
return itemlist
#Function to insert values from tk.Entry boxes to database
def additem_db(val, ref):
conn = sqlite3.connect("demo.db")
cur = conn.cursor()
cur.execute("INSERT OR IGNORE INTO demotable VALUES (NULL, ?, ?)",(val,ref))
conn.commit()
conn.close()
#Function to query database for individual record to populate tk.Entry boxes when item is clicked in lb1
def select_item(val):
conn = sqlite3.connect("demo.db")
cur = conn.cursor()
cur.execute("SELECT * FROM demotable WHERE val=?",(val))
results = cur.fetchall()
itemdetail = list(itertools.chain(*results))
conn.commit()
conn.close()
return itemdetail
l1 = tk.Label(self, text="Values in database:")
l1.grid(row=0, column=0, padx=5, pady=5)
lb1 = tk.Listbox(self, selectmode=tk.SINGLE)
lb1.grid(row=1, column=0, padx=5, pady=5)
popitemlist(self)
lb1.bind("<Button-1>", selectitem)
l2 = tk.Label(self, text="Type val into entry box to store:")
l2.grid(row=0, column=1, padx=5, pady=5)
val = tk.StringVar(self)
val_entry = tk.Entry(self, textvariable=val)
val_entry.grid(row=0, column=2, padx=5, pady=5)
l2 = tk.Label(self, text="Type ref into entry box to store:")
l2.grid(row=1, column=1, padx=5, pady=5)
ref = tk.StringVar(self)
ref_entry = tk.Entry(self, textvariable=ref)
ref_entry.grid(row=1, column=2, padx=5, pady=5)
b1 = tk.Button(self, text="Add item",command=additem)
b1.grid(row=2, column=2, padx=5, pady=5)
app = demo()
app.geometry("480x240")
app.mainloop()
```
谢谢您,如果我的代码冒犯了任何人,我们深表歉意!