Related
I just start learning tkinter python for knapsack program. When I try to calculate, it doesn't do anything. And I am getting this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/tkinter/init.py", line 1921, in call
return self.func(*args)
TypeError: knapSack() missing 3 required positional arguments: 'W', 'wt', and 'val'
My code looks like this
import tkinter as tk
window = tk.Tk()
window.title("0/1 Knapsack")
canvas = tk.Canvas(window, height=1000, width=1000, bg = "#ADD8E6")
canvas.pack()
frame = tk.Frame(window, bg="white")
frame.place(relwidth=0.8, relheight=0.8,relx=0.1,rely=0.1)
def on_submit():
num_entries = int(num_entries_entry.get())
for i in range(num_entries):
Title_label = tk.Label(frame, text = "Items information")
Title_label.grid(row=5, column=1)
Title_label.config(font=("Arial", 18))
entry = tk.Entry(frame)
entry_label = tk.Label(frame, text = " Weight of items : " )
entry_label.grid(row=6,column=0)
entry.grid(row=7+i, column=0)
entry2 = tk.Entry(frame)
entry2_label = tk.Label(frame, text = " Value of each items")
entry2_label.grid(row=6, column=1)
entry2.grid(row=7+i, column=1)
capacity_label = tk.Label(frame, text =" Please select the capacity of your bag :")
capacity_spinbox = tk.Spinbox(frame, from_=1, to=100 )
capacity_label.grid(row=6, column=2)
capacity_spinbox.grid(row=7,column=2)
calculate_button =tk.Button(frame,text="Calculate", command = knapSack)
calculate_button.grid(row=7,column=3)
def calculate(weights, values, capacity):
result = knapSack(capacity, weights, values)
# Create a label to display the result
result_label = tk.Label(frame, text="Result: " + str(result))
result_label.grid(row=14, column=0)
def print_value_table(table):
print("Value Table:")
for row in table:
print(row)
def print_keep_table(table):
print("Keep Table:")
for row in table:
print(row)
def knapSack(W, wt, val):
n=len(val)
value_table = [[0 for x in range(W + 1)] for x in range(n + 1)]
keep_table = [[0 for x in range (W+1)] for x in range (n+1)]
for i in range(n + 1):
for j in range(W + 1):
if i == 0 or j == 0:
value_table[i][j] = 0
keep_table[i][j] = 0
elif wt[i-1] <= j:
if(val[i-1] + value_table[i-1][j-wt[i-1]]) > value_table[i-1][j]:
value_table[i][j] = val [i-1]+ value_table[i-1][j-wt[i-1]]
keep_table [i][j] = 1
else:
value_table[i][j] = value_table[i-1][j]
keep_table[i][j] = 0
else:
value_table[i][j] = value_table[i-1][j]
keep_table[i][j] = 0
print_value_table(value_table)
print_keep_table(keep_table)
return value_table[n][W]
num_entries_label = tk.Label(frame, text="Enter the number of items:")
num_entries_label.grid(row=1, column=1)
num_entries_entry = tk.Entry(frame)
num_entries_entry.grid(row=2, column=1)
next_button = tk.Button(frame, text="Next", command=on_submit)
next_button.grid(row=3, column=1)
title_label = tk.Label(frame, text = "Hi! Please follow the instructions!")
title_label.config(font=("Arial", 18))
window.mainloop()
I want to connect calculator gui with function graph gui.
For example
if I clicked 'sinx' on the calculator, the graph(which is sine function) would be apear on graph gui.
How could I do?
Calculator GUI code
from tkinter import *
window = Tk()
window.title("해대비주얼")
''
top_row = Frame(window)
top_row.grid(row=0, column=0, columnspan=2, sticky=N)
display = Entry(top_row, width=35, bg="light blue")
display.grid()
num_pad = Frame(window)
num_pad.grid(row=1, column=0, sticky=W)
num_pad_list = [
'7','8','9',
'4','5','6',
'1','2','3',
'0','.','=']
r = 0
c = 0
for btn_text in num_pad_list:
def cmd(x=btn_text):
click(x)
Button(num_pad, text=btn_text, width=5, command=cmd).grid(row=r, column=c)
c = c + 1
if c > 2:
c = 0
r = r + 1
operator = Frame(window)
operator.grid(row=1, column=1, sticky=E)
operator_list = [
'*','/',
'+','-',
'(',')',
'^','C']
r = 0
c = 0
for btn_text in operator_list:
def cmd(x=btn_text):
click(x)
Button(operator, text=btn_text, width=5, command=cmd).grid(row=r, column=c)
c = c + 1
if c > 1:
c = 0
r = r + 1
etc = Frame(window)
etc.grid(row=50, column=0, sticky=S)
etc_list = ['pi','sin','cos','x']
r = 0
c = 0
for btn_text in etc_list:
def cmd(x=btn_text):
click(x)
Button(etc, text=btn_text, width=5, command=cmd).grid(row=r, column=c)
r = 0
c = c + 1
def click(key):
if key == "=":
try:
if "^" in display.get():
n = display.get().split(sep="^")
result = str(float(n[0]) ** float(n[1]))
display.insert(END, " = " + result)
else:
result = str(eval(display.get()))[0:10]
display.insert(END, " = " + result)
except:
display.insert(END, " --> Error!")
elif key == "C":
display.delete(0, END)
elif key == etc_list[0]:
import math
display.insert(END, math.pi)
else:
display.insert(END, key)
window.mainloop()
2.Graph GUI code
from tkinter import *
graph = Tk()
graph.title("해대비주얼 그래프")
''
graph.geometry("1000x700")
''
My A-level project is an alarm system I have built using Tkinter that calculates the nearby traffic and changes your alarm time depending on how much the traffic will slow down or increase your journey.
I have calculated all the times I need, however, now I face the problem of having to constantly poll the current time to check it against my own, but this stops my tkinter functions from running. I am now fearing I should have used a different object orientated language.
How can I run these functions at the same time?
My code is below (I'm sure it is very inefficient).
def __init__(self, master = None): #initialising the frame setup for windows
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
global lb,a,n
self.master.title("Alarm")
self.pack(fill=BOTH, expand =1)
newButton = Button(self, text="New Alarm", command=self.new_window) #create buttons and link to commands
newButton.place(x=50, y=50)
deleteButton = Button(self, text="Delete Alarm", command = self.alarmDelete)
deleteButton.place(x=250, y=50)
n=0 #loop through to find out how many rows are in the database
for row in c.execute('SELECT Start Destination FROM stocks '):
n = n + 1
i=0
remove=")"
removed="("
removing=","
remover="'"
a = [[0] * 14 for i in range(n)] #load database into multidimensional array
for row in c.execute('SELECT Start Destination FROM stocks '):
a[i][0]= row
temp=""
for j in str(a[i][0]): #remove unwanted characters from vars
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][0]=temp
i = i + 1
i=0
for row in c.execute('SELECT End Destination FROM stocks '):
a[i][1]= row
temp=""
for j in str(a[i][1]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][1]=temp
i = i + 1
i=0
for row in c.execute('SELECT hArrival FROM stocks '):
a[i][2]= row
temp=""
for j in str(a[i][2]):
if j==remove or j == removed or j == removing or j==remover :
null=""
else:
temp=temp + str(j)
a[i][2]=temp
i = i + 1
i=0
for row in c.execute('SELECT mArrival FROM stocks '):
a[i][3]= row
temp=""
for j in str(a[i][3]):
if j==remove or j == removed or j == removing or j == remover:
null=""
else:
temp=temp + str(j)
a[i][3]=temp
i = i + 1
i=0
for row in c.execute('SELECT Preperation Time FROM stocks '):
a[i][4]= row
temp=""
for j in str(a[i][4]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][4]=temp
i = i + 1
i=0
for row in c.execute('SELECT Day Date FROM stocks '):
a[i][5]= row
temp=""
for j in str(a[i][5]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][5]=temp
i = i + 1
i=0
for row in c.execute('SELECT Month Date FROM stocks '):
a[i][6]= row
temp=""
for j in str(a[i][6]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][6]=temp
i = i + 1
i=0
for row in c.execute('SELECT Year Date FROM stocks '):
a[i][7]= row
temp=""
for j in str(a[i][7]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][7]=temp
i = i + 1
i=0
for row in c.execute('SELECT AlarmName FROM stocks '):
a[i][10]= row
temp=""
for j in str(a[i][10]):
if j==remove or j == removed or j == removing or j ==remover :
null=""
else:
temp=temp + str(j)
a[i][10]=temp
i = i + 1
i=0
for i in range(n):#convert times and dates to timestamp and datestamps
a[i][8] = int(a[i][2])*3600 + int(a[i][3])*60
a[i][9] = str(a[i][6]) + "/" + str(a[i][5]) + "/" + str(a[i][7])
i=i+1
i=0
for i in range(n): #set all boolean value to true for later validation in calc
a[i][12] = "00:00"
a[i][12] = datetime.strptime(a[i][12], '%H:%M').time()
i=i+1
for i in range(n): #set all boolean value to true for later validation in calc
a[i][13] = 0
i=i+1
i=0
lb=Listbox(root) #create listbox and insert values
lb.pack()
for i in range(n):
for item in [str(a[i][10])]:
lb.insert(END, item)
i=i+1
lb.bind('<Double-Button-1>', Window.alarmInfo) #if list item is double clicked call alarmInfo
Window.alarmCalc(self) #call calculations
def alarmInfo(self): #finds out which listbox item was selcted and prints info about it
global lb,a,n
listName = lb.get(ACTIVE)
i=-1
for i in range(n):
if listName == a[i][10]:
break
else:
i=i+1
window = Toplevel(root)
window.geometry("200x150")
Label(window, text="Start Destination:").grid(row=0, sticky=W)
Label(window, text=a[i][0]).grid(row=0,column=1, sticky=W)
Label(window, text="End Destination:").grid(row=1, sticky=W)
Label(window, text=a[i][1]).grid(row=1,column=1, sticky=W)
Label(window, text="Arrival Time:").grid(row=2, sticky=W)
Label(window, text=a[i][2] + ":" + a[i][3]).grid(row=2,column=1, sticky=W)
Label(window, text="Preperation Time:").grid(row=3, sticky=W)
Label(window, text=a[i][5]).grid(row=3,column=1, sticky=W)
Label(window, text="Date").grid(row = 4,column=0, sticky=W)
Label(window, text=a[i][9]).grid(row=4,column=1, sticky=W)
Label(window, text="Alarm Name:").grid(row=5, sticky=W)#
Label(window, text=a[i][10]).grid(row=5,column=1, sticky=W)
def alarmDelete(self):
global a,n,lb
listName = lb.get(ACTIVE)
i=-1
for i in range(n):
if listName == a[i][10]:
break
else:
i=i+1
for row in c.execute('SELECT AlarmName FROM stocks '): #deletes selected item from database
temp = row
if listName in temp:
c.execute('DELETE FROM stocks WHERE AlarmName=?', (listName,))
conn.commit()
break
def new_window(self): #create new window, and initialise layout
global eSd,eEd,eAth,eAtm,ePt,eDd,eDm,eDy,eAn
window = Toplevel(root)
window.geometry("550x300")
Label(window, text="Start Destination").grid(row=0, sticky=W)
Label(window, text="End Destination").grid(row=1, sticky=W)
Label(window, text="Arrival Time").grid(row=2, sticky=W)
Label(window, text=":").grid(row=2, column=2, sticky=W)
Label(window, text="Preperation Time").grid(row=3, sticky=W)
Label(window, text="Alarm Name").grid(row=5, sticky=W)#
eSd = Entry(window, width=5)
eEd = Entry(window,width=5)
eAth = Spinbox(window, from_=0, to=23)
eAtm = Spinbox (window, from_=0, to=59)
eDd = Spinbox (window, from_=1, to=31)
eDm = Spinbox (window, from_=1, to=12)
eDy = Spinbox (window, from_=2017, to=2019)
ePt = Entry(window,width=5)
eAn = Entry(window, width=20)
eSd.grid(row=0, column=1, sticky=W)
eEd.grid(row=1, column=1, sticky=W)
eAth.grid(row=2, column=1, sticky=W)
eAtm.grid(row=2,column=3, sticky=W)
ePt.grid(row=3, column=1, sticky=W)
eAn.grid(row=5, column=1, sticky=W)#
Label(window, text="Date").grid(row = 4,column=0, sticky=W)
eDd.grid(row = 4,column=3, sticky=W)
Label(window, text="/").grid(row = 4,column=2, sticky=W)
eDm.grid(row = 4,column=1, sticky=W)
Label(window, text="/").grid(row = 4,column=4, sticky=W)
eDy.grid(row = 4,column=5, sticky=W)#
createButton = Button(window, text ="Create", command = self.create) #link to def create()
createButton.place(x =50,y=150)
def create(self):
global eSd,eEd,eAth,eAtm,ePt,eDd,eDm,eDy,eAn
global sd,ed,ath,atm,pt,Dd,Dm,Dy,an
val1 = False
val2 = False
val3 = True
error=""
sd = eSd.get()
ed = eEd.get()
ath = eAth.get()
atm = eAtm.get()
pt = ePt.get()
Dd = eDd.get()
Dm = eDm.get()
Dy = eDy.get()
an = eAn.get()#
with open('zipcode.csv') as csvfile: #check through csv file to validate zipfiles
reader = csv.reader(csvfile)
for row in reader:
for col in row:
if col == sd:
val1= True
if col ==ed:
val2 = True
if len(pt) < 5: #validate pt
try:
val3 = int(pt)
except ValueError:
val3 = False
else:
val3 = False
if val1 == False and val2 == False and val3 == False: #Compare boolean values to generate correct error message
error = "Invalid Prep Time and Zipcodes"
elif val1 == False and val3 == False :
error = "Invalid Prep Time and Start Zipcode"
elif val1 == False and val2 == False :
error = "Invalid Zipcodes"
elif val2==False and val3==False:
error= "Invalid Prep Time and End Zipcode"
elif val1 == False:
error="Invalid Start Zipcode"
elif val2==False:
error="Invalid End Zipcode"
elif val3==False:
error = "Invalid Prep Time"
if val1 == False or val2 == False or val3 == False: #call different function depending on errors
Window.valEr(self,error)
else:
Window.addList(self)
def valEr(self, error): #displays error message
window = Toplevel(root)
window.geometry("100x100")
Label(window, text=error).place(x=40, y=40)
def addList(self):
global sd,ed,ath,atm,pt,Dd,Dm,Dy,an#
if len(ath)< 2: #add preceeding 0's to single values to make calculations easier
ath = "0" + ath
if len(atm) < 2:
atm = "0" + atm
if len(Dm) < 2:
Dm = "0" + Dm
if len(Dd) <2:
Dd = "0" + Dd
pt = int(pt) * 60
writeTo = (sd,ed,ath,atm,pt,Dd,Dm,Dy,an) #create tuple to make writing to database easier
c.execute("INSERT INTO stocks VALUES(?,?,?,?,?,?,?,?,?)", writeTo) #insert data into database
conn.commit()
#################################################################################
def alarmCalc(self):
global a,n
x=1000000000000000000000000
i=0
nowDate = date.today()
temp =""
temp2 = ""
nowDate = str(nowDate.month) + "/" + str(nowDate.day) + "/" + str(nowDate.year) #get todays date
for i in range(n):
if nowDate == a[i][9]:
Link= 'https://www.mapquestapi.com/directions/v2/route?key=YCGaovp1Y6fRO5f1RVWv2c1Qs9F4qF1N&from='+str(a[i][0])+'%2C+NY&to='+str(a[i][1])+'%2C+NY&outFormat=json&routeType=fastest&avoidTimedConditions=true&narrativeType=none'
response = requests.get(Link)
data = json.loads(response.text)
rawtravelTime =int( data["route"]["time"]) #request and retrieve correct time
#print(rawtravelTime)
a[i][11]= int(a[i][8]) - int(a[i][4]) - rawtravelTime #calculate time in seconds
#print(a[i][11])
m, s = divmod(a[i][11], 60) # convert seconds to time using quotients
h, m = divmod(m, 60)
a[i][11]= str("%d:%02d:%02d" % (h, m, s))
a[i][11] = a[i][11][:-3] #validation of time string
if len(a[i][11]) < 5:
a[i][11] = "0" + a[i][11]
a[i][11] = datetime.strptime(a[i][11], '%H:%M').time() #turn into datetime object
#print(a[i][11])
nowTime = datetime.now().strftime('%H:%M') #get current time
nowTime = datetime.strptime(nowTime, '%H:%M').time()
#print(nowTime)
if a[i][11] < nowTime or a[i][11] == nowTime or x < (10*3600) : #if alarm time = or exceeds current time call alarmTrig
Window.alarmTrig(self)
else:
#print("NO")
a[i][12] = datetime.combine(date.min, a[i][11]) - datetime.combine(date.min, nowTime)
temp = str(a[i][12])
print(temp)
if len(temp) > 7: # gets time left in seconds
temp2 = temp[4:6]
temp = temp[:2]
a[i][13] = (int(temp) *3600) + (int(temp2) *60)
print(a[i][13])
else:
temp2 = temp[2:4]
temp = temp[:1]
a[i][13] = (int(temp) *3600) + (int(temp2) *60)
print(a[i][13])
# i=i+1
else:
# i=i+1
print("not date")
for i in range(n): #finds smallest time
if int(a[i][13]) < int(x):
x=int(a[i][13])
print(x)
time.sleep(x/2) #make it wait half the time before recalc
Window.alarmCalc
def alarmTrig(self):
print("TRIG")
winsound.PlaySound("*", winsound.SND_ALIAS)
#Delete alarm
I am currently making a Tic-Tac-Toe game, and I am working on trying to check if someone gets 3 of their pieces in a row, so I can tell them they've won. I'm trying to do that by checking the text of the buttons, to see if I've gotten 3 in a row. However, I don't know how to check the text of a specific button in a list. Does anyone have any ideas, or if there is a better way, can you let me know?
Full Code
import tkinter as tk
class TicTacToe(tk.Tk):
def __init__(self):
super().__init__()
# Vars
self.rounds_played = 0
self.wins = 0
self.losses = 0
self.player = 0
self.turn = 0
self.clicked_buttons = []
# Attributes
self.resizable(False, False)
self.attributes("-toolwindow", True)
# Start
self.game_title = tk.Label(text="Stew's Tic Tac Toe")
self.name_label = tk.Label(text="Choose a name\n(Press the \'Enter\' key to submit)")
self.name_entry = tk.Entry()
self.symbol_label = tk.Label(text="Choose your symbol")
self.symbol_buttons = [tk.Button(text="[X]", command=lambda: self.symbol_select(0)),
tk.Button(text="[O]", command=lambda: self.symbol_select(1))]
self.next = tk.Button(text="Next", command=self.next_button)
self.ready = tk.Button(text="Start", command=self.start_game_button)
self.game_title.grid(row=0)
self.name_label.grid(row=1)
self.name_entry.grid(row=2)
self.name_entry.bind("<Return>", lambda x: self.set_player_name(self.player))
def set_player_name(self, num):
if num == 0:
self.names = [self.name_entry.get()]
if self.names[0] == " ":
self.names = ["Player 1"]
print(self.names[0])
self.symbol_label.grid(row=3,)
self.symbol_buttons[0].grid(row=4, sticky=tk.W, padx=57.5)
self.symbol_buttons[1].grid(row=4, sticky=tk.E, padx=57.5)
elif num == 1:
self.names.append(self.name_entry.get())
if self.names[1] == "" or " ":
self.names.append("Player 2")
self.ready.grid(row=4)
def symbol_select(self, num):
if num == 0:
self.symbol = ["[X]",
"[O]"]
else:
self.symbol = ["[X]",
"[O]"]
self.next.grid(row=5)
def next_button(self):
self.player = 1
self.next.grid_forget()
self.name_entry.delete(0, tk.END)
self.symbol_label.grid_forget()
for x in self.symbol_buttons:
x.grid_forget()
def start_game_button(self):
self.game_title.grid_configure(row=0, column=1, columnspan=3)
self.whos_turn = tk.Label(text="{}\'s turn".format(self.names[0]))
self.whos_turn.grid(row=1, column=1, columnspan=3)
self.ready.grid_forget()
self.name_label.grid_forget()
self.name_entry.grid_forget()
self.game_buttons = [tk.Button(text="[ ]", command=lambda: self.move_update(0)),
tk.Button(text="[ ]", command=lambda: self.move_update(1)),
tk.Button(text="[ ]", command=lambda: self.move_update(2)),
tk.Button(text="[ ]", command=lambda: self.move_update(3)),
tk.Button(text="[ ]", command=lambda: self.move_update(4)),
tk.Button(text="[ ]", command=lambda: self.move_update(5)),
tk.Button(text="[ ]", command=lambda: self.move_update(6)),
tk.Button(text="[ ]", command=lambda: self.move_update(7)),
tk.Button(text="[ ]", command=lambda: self.move_update(8))]
num = 0
for r in range(0,3):
for c in range(0,3):
self.game_buttons[num].grid(row=(r%3 + 2), column=(c%3 + 1))
num = num + 1
self.rounds = tk.Label(text="Rounds Played: {}".format(self.rounds_played))
self.rounds.grid(row=5, column=1, columnspan=3)
def move_update(self, num):
if num not in self.clicked_buttons:
self.clicked_buttons.append(num)
self.turn = self.turn + 1
if self.turn%2 == 1:
self.game_buttons[num].config(text=self.symbol[0])
elif self.turn%2 == 0:
self.game_buttons[num].config(text=self.symbol[1])
# Here is where I am struggling
for x in range(0,8):
if self.game_buttons[x] == "[X]" and self.game_buttons[(x+3)%9]:
if self.game_buttons[(x+6)%9] == "[X]":
print("Winner")
# Here is where it ends
if self.turn == 9:
self.rounds_played = self.rounds_played + 1
self.rounds.configure(text="Rounds Played: {}".format(self.rounds_played))
self.play_again = tk.Button(text="Play Again?", command=self.new_game)
self.play_again.grid(row=6, column=1, columnspan=3)
def new_game(self):
self.turn = 0
game = TicTacToe()
game.mainloop()
Part I am struggling with
for x in range(0,8):
if self.game_buttons[x] == "[X]" and self.game_buttons[(x+3)%9]:
if self.game_buttons[(x+6)%9] == "[X]":
print("Winner")
I realize in this part I'm not finding the text, but I really don't know how to call upon both the specific list item and text.
Calling the element in a list which contains a tkinter Button widget will return the widget itself as if you were calling any other value stored in an element of a list. Meaning that if you wanted the text attribute of the value of the element you could use ["text"] or .cget("text").
See below:
from tkinter import *
root = Tk()
array = [Button(root, text="1"), Button(root, text="2"), Button(root, text="3")]
for i in array:
print(type(i))
print(i.cget("text"))
print(i["text"])
I have a Python program that gets information from a database; in this case, we're making hotel reservations. My issue is that if I use checkboxes and select multiple rooms--only the first in the list shows up. I believe the error to be a counting error of sorts that resides in my checkDetails method.
It would appear, then when trying to get the value of the checkbox, it only works for the first checkbox in the list. To be perfectly honest, I'm not 100% sure how to describe the issue. In lieu of words, I've uploaded four gifs showing the issue.
GOOD: Selecting the first two works fine. Selecting the first item alone works as well. No matter what, the first item always works.
BAD_1:Selecting the first item and another item (any item except the second) only displays the first item regardless.
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')
EDIT: Why not just do this?
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
Definitely one problem is that you're creating more than one instance of tk.Tk(). Tkinter isn't designed to work that way, and it will yield problems similar to what you're seeing.
If you need additional windows, you must create instances of tk.Toplevel.
Another problem is this loop:
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
There is a fundamental flaw in the logic. Even though you loop over the data, you keep checking self.vars[new_count]. So, even though you eventually land on data item 3, 4, 5, etc, you keep checking self.vars[0] over and over and over. Once you find one checked item, you now keep looking at self.vars[1] even though you may now be on data item number 3, 4, 5, etc.
One simple fix is to make sure you're iterating over the variables the same as you are iterating over the data values:
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
The above assumes there is a 1:1 relationship between the items in self.vars and the items in self.data. It's hard to tell if that's a valid assumption or not.