我有一个Python程序,可以从数据库中获取信息;在这种情况下,我们正在预订酒店。我的问题是,如果我使用复选框并选择多个房间 - 只显示列表中的第一个。我认为该错误是我的checkDetails
方法中存在的排序计数错误。
然后会出现,然后在尝试获取复选框的值时,它仅适用于列表中的第一个复选框。说实话,我并不是100%确定如何描述这个问题。取而代之的是,我上传了四个显示此问题的GIF。
BAD_2: Selecting any two items that don't involve the first item, results in neither item being displayed.
BAD_3: Selecting any single item that isn't the first item results in it not being displayed.
##(USER)MAKE NEW RESERVATION##
def searchReservation(self):
self.root = tk.Tk()
self.root.title("Search Rooms")
# city option button
self.cityvariable = StringVar(self.root)
self.cityvariable.set("Select City")
w = OptionMenu(self.root, self.cityvariable, "Atlanta", "Charlotte",
"Savannah", "Orlando", "Miami").grid(row=0, column=0)
# start and end labels
self.startDate = tk.Label(
self.root, text="Start Date (YYYY-MM-DD)") .grid(row=1, column=0)
self.endDate = tk.Label(
self.root, text="End Date (YYYY-MM-DD)").grid(row=1, column=1)
# start and end entries
self.startStringEntry = tk.Entry(self.root, state=NORMAL, width=10)
self.startStringEntry.grid(row=2, column=0)
self.startStringEntry.insert(0, '2015-11-23') #TODO debugging--remove
self.endStringEntry = tk.Entry(self.root, state=NORMAL, width=10)
self.endStringEntry.grid(row=2, column=1)
self.endStringEntry.insert(0, '2015-11-25') #TODO debugging--remove
# search button
self.search_button = tk.Button(
self.root, text="Search Availabilities", command=self.makeReservation)
self.search_button.grid()
self.root.mainloop()
def validDate(self, date):
correctdate = None
try:
startdate = datetime.datetime.strptime(date, "%Y-%m-%d")
correctdate = True
except ValueError:
correctdate = False
if correctdate is False:
messagebox.showerror(
title="Warning", message="A valid date format is required.")
return correctdate
def makeReservation(self):
if self.startStringEntry.get() == self.endStringEntry.get():
messagebox.showerror(
title="Warning", message="Reservation must be at least a day")
elif not self.validDate(self.startStringEntry.get()) or not self.validDate(self.endStringEntry.get()):
return
elif datetime.datetime.strptime(self.startStringEntry.get(), '%Y-%m-%d') > datetime.datetime.strptime(self.endStringEntry.get(), '%Y-%m-%d'):
messagebox.showerror(
title="Warning", message="End date must be after start date")
else:
self.search_button.config(state='disabled')
self.root.withdraw()
self.makeRes = tk.Tk()
self.makeRes.title("Make a Reservation")
# date labels
Label(self.makeRes, text="Start Date") .grid(row=0, column=0)
Label(self.makeRes, text="End Date").grid(row=0, column=1)
Label(self.makeRes, text=self.startStringEntry.get()).grid(
row=1, column=0)
Label(self.makeRes, text=self.endStringEntry.get()).grid(
row=1, column=1)
Label(self.makeRes, text='City').grid(row=0, column=2)
Label(self.makeRes, text=self.cityvariable.get()).grid(
row=1, column=2)
# column headers
roomnumber = tk.Label(
self.makeRes, text="Room Number").grid(row=2, column=0)
roomcat = tk.Label(self.makeRes, text="Room Category").grid(
row=2, column=1)
capacity = tk.Label(
self.makeRes, text="Room Capacity").grid(row=2, column=2)
costperday = tk.Label(
self.makeRes, text="Cost Per Day").grid(row=2, column=3)
costextra = tk.Label(
self.makeRes, text="Extra Bed Cost").grid(row=2, column=4)
availability = tk.Label(
self.makeRes, text="Select Room").grid(row=2, column=5)
# insert available rooms
sql = """SELECT a.RoomNum, a.Category, b.RoomCapacity, a.CostPerDay, a.ExtraBedCost
FROM ROOM a, ROOM_CAPACITY b
WHERE a.Category = b.Category
AND a.RoomLocation = '""" + self.cityvariable.get() + """'
AND (
a.RoomNum, a.RoomLocation
) NOT
IN (
SELECT DISTINCT c.RoomNum, c.Location
FROM ROOM_RESERVATION c, RESERVATION d
WHERE c.ReservationID = d.ReservationID
AND c.Location = a.RoomLocation
AND d.RefundAmount IS NULL
AND """ + self.endStringEntry.get() + """ <= d.EndDate
AND """ + self.startStringEntry.get() + """ >= d.StartDate
)"""
cursor.execute(sql)
self.count = 3
self.data = []
for data in cursor:
self.data.append(data)
for i in range(5):
Label(self.makeRes, text=data[i]).grid(
row=self.count, column=i)
self.count = self.count + 1
if self.count == 3:
messagebox.showerror(
title="Warning", message="No rooms available for city and dates")
self.makeRes.destroy()
self.searchReservation()
else:
# making checkboxes to select room
self.vars = []
for rowNum in range(3, self.count):
self.var = IntVar(self.makeRes)
Checkbutton(self.makeRes, variable=self.var).grid(
row=rowNum, column=5)
self.vars.append(self.var)
self.check_detail_button = Button(
self.makeRes, text='Check Details', command=self.checkDetails)
self.check_detail_button.grid(row=self.count + 1, column=5)
def checkDetails(self):
noneselected = True
for i in self.vars:
if i.get() == 1:
noneselected = False
break
if noneselected is True:
messagebox.showerror(title="Warning", message="No rooms selected")
else:
self.check_detail_button.config(state='disabled')
ttk.Separator(self.makeRes, orient=HORIZONTAL).grid(
column=0, row=self.count+2, columnspan=10, sticky=(W, E))
# column headers
Label(self.makeRes, text="Room Number").grid(
row=self.count + 3, column=0)
Label(self.makeRes, text="Room Category").grid(
row=self.count + 3, column=1)
Label(self.makeRes, text="Room Capacity").grid(
row=self.count + 3, column=2)
Label(self.makeRes, text="Cost Per Day").grid(
row=self.count + 3, column=3)
Label(self.makeRes, text="Extra Bed Cost").grid(
row=self.count + 3, column=4)
Label(self.makeRes, text="Select Extra Bed").grid(
row=self.count + 3, column=5)
self.count += 4
new_count = 0
for data in self.data:
print(data, self.vars[new_count].get()) #TODO remove
if self.vars[new_count].get() == 1:
for i in range(5):
Label(self.makeRes, text=data[i]).grid(
row=self.count + new_count, column=i)
new_count += 1
# making checkboxes to select beds
self.beds = []
count = 0
for rowNum in range(self.count, self.count + new_count):
if self.vars[count].get() == 1:
var = IntVar(self.makeRes)
checkBox = tk.Checkbutton(
self.makeRes, variable=var).grid(row=rowNum, column=5)
self.beds.append(var)
count += 1
self.count += new_count
Label(self.makeRes, text='Total Cost').grid(
row=self.count + 1, column=2)
# CALCULATE TOTAL COSTS
total_cost = 0
count = 0
self.new_data = []
for i in self.data:
if self.vars[count].get() == 1:
total_cost += i[3]
self.new_data.append(i)
count += 1
val = str(total_cost)
self.total_costs_entry = Entry(self.makeRes)
self.total_costs_entry.grid(row=self.count + 1, column=3)
self.total_costs_entry.insert(0, val)
self.total_costs_entry.config(state='readonly')
Button(self.makeRes, text='Update total', command=self.updateTotalCosts).grid(
row=self.count + 1, column=4)
Label(self.makeRes, text='Use Card').grid(
row=self.count + 2, column=2)
cursor.execute(
'SELECT CardNum FROM PAYMENT_INFO WHERE Username="' + self.user + '"')
cards = ['-']
for i in cursor:
cards.append(i)
self.card = StringVar(self.makeRes)
self.opts = OptionMenu(self.makeRes, self.card, *cards)
self.opts.grid(row=self.count + 2, column=3)
Button(self.makeRes, text="Add Card", command=self.addCreditCard).grid(
row=self.count + 2, column=4)
Button(self.makeRes, text="Delete Card", command=self.deleteCard).grid(
row=self.count + 2, column=5)
Button(self.makeRes, text='Submit', command=self.submitReservation).grid(
row=self.count + 3, column=5)
def updateTotalCosts(self):
total_cost = 0
count = 0
self.new_data = []
for i in self.data:
if self.vars[count].get() == 1:
total_cost += i[3]
self.new_data.append(i)
count += 1
count = 0
for i in self.new_data:
if self.beds[count].get() == 1:
total_cost += i[4]
count += 1
cursor.execute("SELECT DATEDIFF(%s, %s)",
(self.endStringEntry.get(), self.startStringEntry.get()))
diff = cursor.fetchone()
diff = diff[0]
total_cost = diff * total_cost
self.total_costs_entry.destroy()
self.total_costs_entry = Entry(self.makeRes)
self.total_costs_entry.grid(row=self.count + 1, column=3)
self.total_costs_entry.insert(0, str(total_cost))
self.total_costs_entry.config(state='readonly')
编辑:为什么不这样做?
for data in self.data:
print(data, self.vars[new_count].get()) #TODO debugging--remove
if self.vars[new_count].get() == 1:
for i in range(5):
Label(self.makeRes, text=data[i]).grid(
row=self.count + new_count, column=i)
new_count += 1
答案 0 :(得分:2)
绝对有一个问题是您要创建多个tk.Tk()
的实例。 Tkinter并不是设计成以这种方式工作的,它会产生类似于你所看到的问题。
如果您需要其他窗口,则必须创建tk.Toplevel
。
另一个问题是这个循环:
for data in self.data:
if self.vars[new_count].get() == 1:
for i in range(5):
Label(self.makeRes, text=data[i]).grid(
row=self.count + new_count, column=i)
new_count += 1
逻辑存在根本缺陷。即使您遍历数据,也要继续检查self.vars[new_count]
。因此,即使您最终登陆数据项3,4,5等,也要一遍又一遍地检查self.vars[0]
。一旦找到一个选中的项目,即使您现在可以使用数据项目编号3,4,5等,您现在仍然会查看self.vars[1]
。
一个简单的解决方法是确保您在迭代数据值时迭代变量:
for var, data in zip(self.vars, self.data):
if var.get() == 1:
for i in range(5):
Label(self.makeRes, text=str(data[i]) + "?").grid(
row=self.count + new_count, column=i)
new_count += 1
以上假设self.vars
中的项目与self.data
中的项目之间存在1:1的关系。很难说这是否是一个有效的假设。