Trying to get the validate command to work with multiple inputs - python

I'm not at all familiar with Tkinter's validatecommands, but I have done some research and would like to implement it in a widget that creates a tree graph from a bunch of entries. I want to restrict each entry so that the user can create lists of numbers from 0 to the highest row, not including the same row. So, for example, Row 0 entry can't have 0 in it or 12. So far I have only attempted to restrict the input from being the same value as the row, but I haven't been able to get that to work. I must be implementing the validate command incorrectly.
Any help would be much appreciated.
import tkinter as tk
class widget:
def __init__(self,master):
# vcmd = (master.register(self.validate),
# '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
self.master = master
self.entryNumbers = tk.Entry(master,justify = tk.CENTER)
self.entryNumbers.insert(0, "5")
self.entryNumbers.grid(row = 0,column = 0,columnspan =2,sticky="EW")
self.createEntriesButton = tk.Button(master,text = "Create Entries",command = self.createEntries)
self.createEntriesButton.grid(row = 1, column = 0,columnspan = 2,sticky="EW")
def createEntries(self):
self.entryNumbers.grid_forget()
self.createEntriesButton.grid_forget()
self.entries = []
self.entryLabels = []
vcmd = self.master.register(self.validateEntry)
for i in range(int(self.entryNumbers.get())):
self.entryLabels.append(tk.Label(self.master,text = "Row {}".format(i)))
self.entryLabels[-1].grid(row = i,column = 0)
self.entries.append(tk.Entry(self.master, validatecommand=(vcmd,'%P',i)))
self.entries[-1].grid(row = i,column = 1)
self.addEntriesButton = tk.Button(self.master,text = "Add Entries",command = self.addEntry)
self.addEntriesButton.grid(row = i+1, column = 0,columnspan = 2,sticky="EW")
def addEntry(self):
count = len(self.entries)
vcmd = self.master.register(self.validateEntry)
self.entryLabels.append(tk.Label(self.master,text = "Row {}".format(count)))
self.entryLabels[-1].grid(row = count+1,column = 0)
self.entries.append(tk.Entry(self.master, validatecommand=(vcmd,'%P',count)))
self.entries[-1].grid(row = count+1,column = 1)
self.addEntriesButton.grid(row = count+2, column = 0,columnspan = 2,sticky="EW")
def validateEntry(self,P,row):
if P != row:
return True
else:
return False
root1=tk.Tk()
widget(root1)
root1.mainloop()
Also, can vcmd be a member variable? I would like to only initialize it once?

I figured it out using a lambda function:
vcmd = lambda row:(self.master.register(self.validateEntry),'%P',row)
for i in range(int(self.entryNumbers.get())):
self.entryLabels.append(tk.Label(self.master,text = "Row {}".format(i)))
self.entryLabels[-1].grid(row = i,column = 0)
self.entries.append(tk.Entry(self.master, validate = "all", validatecommand=vcmd(i)))

Related

in tkinter.entry using in for loop but when value changed that effect all entery

Here is the code of my application
problem
I have used tkinter Entry() method in for loop in ShowOpeanFile() function and I have make One global list variable where I stored the return value of Entry() but when I enter value in that Entry field it effect on all Entry. But I don't want that.
#importing Required library
import tkinter as tk
from tkinter import filedialog
from tkinter import ttk
import pandas as pd
from functools import reduce
#Global Variables to Store FilePath That OPEAN
Opean_file_path = []
#Making gloabl datagram object store variable
datgramoffileVariable = []
datagram_list = []
finaldatagram_list = []
#get Filename and qauntity
def getvalue(i):
if Opean_file_path[i][2].get().isnumeric():
return Opean_file_path[i][1],Opean_file_path[i][2].get(),Opean_file_path[i][0]
else:
return -1
#variable making function for file that map each open file during converxlsx function
def variablemaking(size):
temp = []
for number in range(size):
temp.append(str(number))
temp = (list(set(temp)))
datgramoffileVariable.clear()
for i in range(len(temp)):
datgramoffileVariable.append(temp[i])
#conevrting all file to dataGram using pandas library
def Converxlsx():
#makingVariable functioncall
variablemaking(len(Opean_file_path))
#Now variable Making function Done
#Go for the convert datagram to file
for i in range(len(datgramoffileVariable)):
datgramoffileVariable[i] = pd.DataFrame(pd.read_excel(Opean_file_path[i][0]))
for i in range(len(datgramoffileVariable)):
print(datgramoffileVariable[i])
#subpart of Compute function find in list return filepath
def find(target):
for i in range(len(Opean_file_path)):
if(Opean_file_path[i][1] == target):
return Opean_file_path[i][0]
return -1
def findindex(tar):
for i in range(len(Opean_file_path)):
print(Opean_file_path[i][0])
if(Opean_file_path[i][0] == tar):
return i
#ComputeFile function
def compute():
for i in range(len(Opean_file_path)):
v = getvalue(i)
if v == -1:
pass
else:
answerOffind = v[0]
if( answerOffind == -1):
if(label_for_error.cget('text') == "enter right file name"):
label_for_error.config(text="")
else:
label_for_error.config(text="enter right file name", fg='red')
else:
label_for_error.config(text="")
if(len(v[1]) == 0 or v[1].isalpha() or v[1] == ' '):
label_for_error.config(text="enter right Qauntity", fg='red')
pass
else:
if v[1].isnumeric():
if(label_for_error.cget('text') == "enter right Qauntity"):
label_for_error.config(text='')
indexofmaniuplation = findindex(v[2])
print(indexofmaniuplation)
datgramoffileVariable[indexofmaniuplation].qauntity = datgramoffileVariable[indexofmaniuplation].qauntity * int(v[1])
# opeanfile function
def ShowOpeanFile():
col = 0
ro = 0
for i in range(len(Opean_file_path)):
ro = ro + 1
for j in range(len(Opean_file_path[i])):
if j > 1:
Opean_file_path[i][j] = tk.Entry(window,width=20,textvariable=1)
Opean_file_path[i][j].grid(row=ro,column=col)
else:
e = tk.Entry(window, width=20, fg='blue')
e.grid(row=ro,column=col)
e.insert(tk.END,Opean_file_path[i][j])
col = col + 1
col = col - 2
for i in range(len(Opean_file_path)):
for j in range(len(Opean_file_path[i])):
print(Opean_file_path[i][j])
#browsefile function
def browseFiles():
#opeanFile only allow Excel file
'''
askopenfile return file path of selected file
it return type is String
'''
filename = filedialog.askopenfilename(initialdir = "/",
title = "Select a File",
filetypes = [("Excel file","*.xlsx"),("Excel file", "*.xls")]
)
#After getting filepath storing into Opean_file_path list
if(filename in Opean_file_path):
pass
else:
tmp = []
tmp.append(filename)
f=filename.split('/')
tmp.append(f[-1])
tmp.append('qauntitybox')
Opean_file_path.append(tmp)
print(tmp)
Converxlsx()
ShowOpeanFile()
# print(Opean_file_path)
#making final CSV File function.
def csv_making():
datagram_list.clear()
finaldatagram_list.clear()
#convert dataframe into list
for i in range(len(datgramoffileVariable)):
datagram_list.extend(datgramoffileVariable[i].values.tolist())
#find repted element and compute all at one single
repted_element = []
datagram_index_to_be_removed=[]
for i in range(len(datagram_list)):
temp_id = datagram_list[i][0]
temp_Qauntity = datagram_list[i][1]
for j in range(i+1,len(datagram_list)):
if datagram_list[j][0] == temp_id:
temp_Qauntity = temp_Qauntity + datagram_list[j][1]
datagram_index_to_be_removed.append(j)
datagram_index_to_be_removed.append(i)
if [temp_id,temp_Qauntity] not in repted_element and datagram_list[j][0] == temp_id:
repted_element.append([temp_id,temp_Qauntity])
datagram_index_to_be_removed = list(tuple(datagram_index_to_be_removed))
#remove repeted element
datagram_index_to_be_removed.sort()
for i in range(len(datagram_list)):
if i in datagram_index_to_be_removed:
pass
else:
finaldatagram_list.append(datagram_list[i])
#add repted_element
for i in repted_element:
finaldatagram_list.append(i)
#print final data
# print(finaldatagram_list)
#convert final list to csv
id = []
qauntityto = []
for i in range(len(finaldatagram_list)):
id.append(finaldatagram_list[i][0])
qauntityto.append(finaldatagram_list[i][1])
dict = {'id':id,'qauntity':qauntityto}
df = pd.DataFrame(data=dict)
pathofnewfile = df.to_csv('/home/vegg/Desktop/out.csv',index=False)
print(pathofnewfile)
label_for_error.config(text='file save at /home/vegg/Desktop/out.csv',fg='blue')
#UI
window = tk.Tk()
scrollbar = tk.Scrollbar()
frame = tk.Frame(window)
window.geometry("750x400")
label_for_qautity = tk.Label(window ,text="Enter the Qauntity",
width=50,height=3)
label_for_qautity.grid(column=2,row=0)
# Qauntity = tk.Entry()
# Qauntity.grid(column=2,row=1)
label_for_fileNamepath = tk.Label(window ,text="File Name path",
width=20,height=3)
label_for_fileNamepath.grid(column=0,row=0)
label_for_fileName = tk.Label(window ,text="File Name",
width=20,height=3)
label_for_fileName.grid(column=1,row=0)
label_for_error = tk.Label(window ,text="",
width=20,height=3)
label_for_error.grid(column=4,row=3)
button_explore = tk.Button(window,
text = "Browse Files here",
command=lambda :[browseFiles()] )
button_Compute = tk.Button(window,
text = "Compute File Data",
command=lambda :[compute()] )
button_CSV = tk.Button(window,
text = "Create CSV Here",
command=lambda :[csv_making()] )
button_explore.grid(column=4,row=0)
button_Compute.grid(column=4,row=1)
button_CSV.grid(column=4, row=2)
window.mainloop()
Image
I want to add different value for entry not same value effect to all entry.

Python-Tk Inter Object Oriented Programming inheriting attributes

So my program is a quiz where there is a main class that is an overall reaction pathway with sub reaction pathways in other classes. How do I inherit the buttons and labels defined in one page like QUESTIONSTARTER and can be displayed on another class which is STAGE 2. This is a big problem for me i hope you can help me. These are examples of the 2 classes: (I couldnt add one more method in question starter) so I want buttons and labels from question starter to be inherited to stage 2 where i can grid the buttons into stage 2.
class SETOFQUESTIONS(QUESTIONSTARTER):
def __init__ (self):
self.NumberOfStages = NumberOfStages
self.StartingReactant = StartingReactant
def SetStages(self, NumberOfStages):
#If the quiz type is default and customised set number of stages to a minimum of 3 stages and a max of 5 stages for aliphatic reaction
#for aromatic -set min stages 2 and max stages 5
if "Default" == True:
self.NumberOfStages = 5
print ("Number Of Stages = ",NumberOfStages)
return NumberOfStages
else:
self.NumberOfStages = CustomisedNumberOfStages
print ("Number Of Stages = ",CustomisedNumberOfStages)
#Sets Max Number of Stages
def SetNonCompulsoryReagents(self):
SetCompulsoryReagentOptionList(self)
ReagentsList = []
while ReagentsList == True:
for count in range (len(ReagentsList)):
try:
sql = ("""SELECT ReagentName FROM NonCompulsoryReagentDatabase \
ORDER BY RAND() \
LIMIT 1""")
conn.execute(sql)
NonCompulsoryReagents = conn.fetchone()
except:
conn.rollback()
if NonCompulsoryReagents[0] != ReagentsList[count]:
ReagentsList.append(NonCompulsoryReagents[0])
ReagentsList = False
elif NonCompulsoryReagents[1] != ReagentsList[count]:
ReagentsList.append(NonCompulsoryReagents[1])
ReagentsList = False
elif NonCompulsoryReagents[2] != ReagentsList[count]:
ReagentsList.append(NonCompulsoryReagents[2])
ReagentsList = False
else:
ReagentsList = True
for Reagent in ReagentsList:
RandomReagent = random.choice(ReagentsList)
ReagentOption1 = tk.Button(bottomFrame, text = RandomReagent, command=lambda: self.AllocatePoints(1))
ReagentOption2 = tk.Button(bottomFrame, text = RandomReagent, command=lambda: self.AllocatePoints(2))
ReagentOption3 = tk.Button(bottomFrame, text = RandomReagent, command=lambda: self.AllocatePoints(3))
ReagentOption4 = tk.Button(bottomFrame, text = RandomReagent, command=lambda: self.AllocatePoints(4))
def SetNonCompulsoryConditions(self):
SetCompulsoryConditionOptionList(self)
sql = ("""SELECT ConditionName FROM NonCompulsoryConditionsDatabase \
ORDER BY RAND () \
LIMIT 1""")
try:
conn.execute(sql)
NonCompulsoryConditions = conn.fetchone()
except:
conn.rollback()
while ConditionsList == True:
for count in range (len(ConditionsList)):
sql = ("""SELECT ConditionName FROM NonCompulsoryConditionsDatabase \
ORDER BY RAND() \
LIMIT 1""")
conn.execute(sql)
NonCompulsoryReagents = conn.fetchone()
if NonCompulsoryConditions[0] != ConditionsList[count]:
ConditionsList.append(NonCompulsoryReagents[0])
ConditionsList = False
elif NonCompulsoryConditions[1] != ConditionsList[count]:
ConditionsList.append(NonCompulsoryConditions[1])
ConditionsList = False
elif NonCompulsoryConditions[2] != ConditionsList[count]:
ConditionsList.append(NonCompulsoryConditions[2])
ConditionsList = False
else:
ConditionsList = True
for Condition in ConditionsList:
RandomCondition = random.choice(ConditionsList)
ConditionOption1 = tk.Button(bottomFrame, text = RandomCondition, command=lambda: self.AllocatePoints(5))
ConditionOption2 = tk.Button(bottomFrame, text = RandomCondition, command=lambda: self.AllocatePoints(6))
ConditionOption3 = tk.Button(bottomFrame, text = RandomCondition, command=lambda: self.AllocatePoints(7))
ConditionOption4 = tk.Button(bottomFrame, text = RandomCondition, command=lambda: self.AllocatePoints(8))
#call at random the specific products from product database
#depending on class run
def ButtonPressed(self,ReagentsList):
ReagentsList[0] = CorrectReagent
self.CorrectReagent.configure(bg = 'green')
IncorrectReagentsList = []
IncorrectReagentsList.append(ReagentsList[1])
IncorrectReagentsList.append(ReagentsList[2])
IncorrectReagentsList.append(ReagentsList[3])
for Reagents in IncorrectReagentsList:
tk.Button[Reagents].configure(bg = "red")
ConditionsList[0] = CorrectCondition
self.CorrectCondition.configure(bg = "green")
IncorrectConditionsList = []
IncorrectConditionsList.append(ReagentsList[1])
IncorrectConditionsList.append(ReagentsList[2])
IncorrectConditionsList.append(ReagentsList[3])
for Reagents in IncorrectReagentsList:
tk.Button[Reagents].configure(bg = "red")
class STAGE2(SETOFQUESTIONS):
def __init__(self,parent, controller):
tk.Frame.__init__(self, parent)
QuestionFrame.tkraise()
controller.show_frame(QuestionFrame)
Question.pack(side = "top")
Question.grid()
ReagentOption1.grid(column = 0,row = 0)
ReagentOption2.grid(column = 0,row = 1)
ReagentOption3.grid(column = 0,row = 2)
ReagentOption4.grid(column = 0,row = 3)
ConditionOption1.grid(column = 0,row = 0)
ConditionOption2.grid(column = 0,row = 1)
ConditionOption3.grid(column = 0,row = 2)
ConditionOption4.grid(column = 0,row = 3)
Continue = tk.Button(StageFrame, text = "Continue", command=lambda: controller.show_frame(Stage2))
Continue.grid(column = 6)
PointsLabel.grid(row=0,column=6)
AttemptsDisplayed.grid(row=1,column=7)

creating an object doesn't work

class phonebook:
def __init__(self,first_name, last_name, street, postcode, city, number):
root = tk.Tk()
root.title('Book')
menubar = tk.Menu(root)
root.config(menu = menubar)
menubar.add_command(label = 'Anlegen', command = self.create)
menubar.add_command(label = 'Bearbeiten', command = self.change)
menubar.add_command(label = 'Löschen')
menubar.add_command(label = 'Sortieren')
menubar.add_command(label = 'Suche')
menubar.add_command(label = 'Hilfe')
root.mainloop()
def printing(self):
account = (self.first_name.get(), self.last_name.get(), self.street.get(), self.postcode.get(), self.city.get(), self.number.get())
accounts.append(account)
for i in accounts:
print(i)
def change(self):
account = accounts[0]
account.first_name = 'test'
self.printing
def create(self):
creation = tk.Toplevel()
tk.Label(creation, text = 'Vorname').grid(row = 1, column = 0)
tk.Label(creation, text = 'Nachname').grid(row = 2, column = 0)
tk.Label(creation, text = 'Stadt').grid(row = 3, column = 0)
tk.Label(creation, text = 'Postleitzahl').grid(row = 4, column = 0)
tk.Label(creation, text = 'Straße').grid(row = 5, column = 0)
tk.Label(creation, text = 'Telefonnummer').grid(row = 6, column = 0)
self.first_name = tk.Entry(creation)
self.last_name = tk.Entry(creation)
self.city = tk.Entry(creation)
self.postcode = tk.Entry(creation)
self.street = tk.Entry(creation)
self.number = tk.Entry(creation)
a = tk.Button(creation, text = 'end', command = self.printing)
self.first_name.grid(row = 1, column = 1)
self.last_name.grid(row = 2, column = 1)
self.city.grid(row = 3, column = 1)
self.postcode.grid(row = 4, column = 1)
self.street.grid(row = 5, column = 1)
self.number.grid(row = 6, column = 1)
a.grid(row = 7, column = 1)
phonebook()
As you can see in my code I'm trying to create and edit objects. The problem is that I cannot create a real object. When I want to create a object with class phonebook, I get this error:
TypeError: __init__() missing 6 required positional arguments: 'first_name', 'last_name', 'street', 'postcode', 'city', and 'number'
What do I have to do so that I don't get this error and so that I can edit the objects?
phonebook must be called with 6 arguments, not 0. You call phonebook(), which causes your code to break. Try calling with something like this:
phonebook("first_name", "last_name", "street", "post_code", "your_city", 123)
substitute in the appropriate values instead of the ones I've provided.
P.S. You won't get much help on this site with a username like that

SQLite Python; writing a value that populates a grid from a slider to the database

I want to populate a SQLite database with a value from a slider widget. I can update a cell using the keyboard but I can't get it to work when the cell is populated from the slider. I am using a button to trigger the population and the write to the database but when I click it, I get a 'sqlite3.OperationError: near "0": syntax error. Here is my code:
import wx
import wx.grid as gridlib
import sqlite3
class Grid(gridlib.Grid):
def __init__(self, parent, db):
gridlib.Grid.__init__(self, parent)
self.CreateGrid(10,5)
for row in range(10):
rowNum = row + 1
self.SetRowLabelValue(row, "cue %s" %rowNum)
self.db = db
self.cur = self.db.con.cursor()
meta = self.cur.execute("SELECT * from CUES")
labels = []
for i in meta.description:
labels.append(i[0])
labels = labels[1:]
for i in range(len(labels)):
self.SetColLabelValue(i, labels[i])
all = self.cur.execute("SELECT * from CUES ORDER by DTindex")
for row in all:
row_num = row[0]
cells = row[1:]
for i in range(len(cells)):
if cells[i] != None and cells[i] != "null":
self.SetCellValue(row_num, i, str(cells[i]))
self.Bind(gridlib.EVT_GRID_CELL_CHANGED, self.CellContentsChanged)
def CellContentsChanged(self, event):
x = event.GetCol()
y = event.GetRow()
val = self.GetCellValue(y,x)
if val == "":
val = "null"
ColLabel = self.GetColLabelValue(x)
InsertCell = "UPDATE CUES SET %s = ? WHERE DTindex = %d"%(ColLabel,y)
self.cur.execute(InsertCell, [(val),])
self.db.con.commit()
self.SetCellValue(y, x, val)
class TestFrame(wx.Frame):
def __init__(self, parent, db):
wx.Frame.__init__(self, parent, -1, "Grid plus db", size = (800,600))
panel = wx.Panel(self, -1)
self.db = db
self.cur = self.db.con.cursor()
sizer = wx.GridBagSizer(vgap=10, hgap=10)
self.slide1 = wx.Slider(panel, -1, 0, 0, 255, size=(50,400),
style=wx.SL_VERTICAL|wx.SL_AUTOTICKS|wx.SL_LABELS|wx.SL_INVERSE)
self.slide1.SetTickFreq(10)
self.Bind(wx.EVT_SCROLL_CHANGED, self.onReport, self.slide1)
self.slide2 = wx.Slider(panel, -1, 0, 0, 255, size=(50,400),
style=wx.SL_VERTICAL|wx.SL_AUTOTICKS|wx.SL_LABELS|wx.SL_INVERSE)
self.slide2.SetTickFreq(10)
self.grid = Grid(panel,db)
self.display = wx.TextCtrl(panel, -1, size=(200,100), style=wx.TE_MULTILINE)
self.aBtn = wx.Button(panel, -1, "Grid")
self.Bind(wx.EVT_BUTTON, self.onPopulate, self.aBtn)
self.bBtn = wx.Button(panel, -1, "Database")
sizer.Add(self.slide1, pos=(0,0))
sizer.Add(self.slide2, pos=(0,1))
sizer.Add(self.grid, pos = (0,2))
sizer.Add(self.aBtn, pos=(1,0))
sizer.Add(self.display, pos=(1,1), span=(2,2))
sizer.Add(self.bBtn, pos=(2,0))
panel.SetSizer(sizer)
panel.Fit()
def onReport(self,event):
val = self.slide1.GetValue()
self.display.WriteText("Slide 1 value = %s\n"%val)
def onPopulate(self, event):
"""Work in Progress"""
val = str(self.slide1.GetValue()) + '\n'
#put a dlg here to get row col - place in SetCellValue(x,y,....
self.grid.SetCellValue(0,0, val) #gets it to the grid...Need to write it to the database
InsertCell = "UPDATE CUES SET %s = ? WHERE DTindex = %d"%(0,0)
self.cur.execute(InsertCell, [(val),])
self.db.con.commit()
class GetDatabase():
def __init__(self, f):
try:
file = open(f)
file.close()
except IOError:
self.exists = 0
else:
self.exists = 1
self.con = sqlite3.connect(f)
if __name__ == "__main__":
import sys
db = GetDatabase("data.db")
app = wx.App()
frame = TestFrame(None, db)
frame.Show(True)
app.MainLoop()
The database was created in DB Browser for SQLite:
CREATE TABLE CUES (
DTindex INTEGER,
A string,
B string,
C string,
D string,
E string,
PRIMARY KEY(DTindex)
);
I think that it's a simple error in this line:
InsertCell = "UPDATE CUES SET %s = ? WHERE DTindex = %d"%(0,0)
0 whilst a valid value for DTindex is a not a valid value for a column name, which would be A,B,C,D or E.
Without knowing exactly what you are attempting to achieve, the following will function.
InsertCell = "UPDATE CUES SET %s = ? WHERE DTindex = %d"%('A',0)
But only if you have a record with a DTindex of 0 (zero), where it replaces the value of the column A with the value from your slider

Python timetable pass start and finish time that pressed button relevant to position

For my coursework i am making a booking system and i have been messing around trying to make a page which shows current week lessons and when the button is clicked it comes up with that students details on a separate page.But i don't know how to go about passing that time into my open page sub(which writes a txt file which is going to be used for SQL to get the students details). The current way i have done it just passes the max times into the sub.
from tkinter import *
import datetime
class Application(Frame):
def __init__(self, master):
""" Initialize the frame. """
super(Application, self).__init__(master)
self.grid()
self.timetable_button_gen_weekdays()
self.timetable_button_gen_weekends()
def timetable_button_gen_weekdays(self):
c = datetime.datetime(100,1,1,16,00,00)
self.Monday_lbl = Label(self, text = "Monday")
self.Monday_lbl.grid(row = 1, column = 0)
self.Tuesday_lbl = Label(self, text = "Tuesday")
self.Tuesday_lbl.grid(row = 2, column = 0)
self.Wednesday_lbl = Label(self, text = "Wednesday")
self.Wednesday_lbl.grid(row = 3, column = 0)
self.Thursday_lbl = Label(self, text = "Thursday")
self.Thursday_lbl.grid(row = 4, column = 0)
self.Friday_lbl = Label(self, text = "Friday")
self.Friday_lbl.grid(row = 5, column = 0)
for k in range(8):
b = c + datetime.timedelta(minutes = (30 * k))
d = b + datetime.timedelta(minutes = (30))
self.i_time_weekdays_lbl = Label(self, text = b.time().strftime('%H:%M')+" to "+d.time().strftime('%H:%M'))
self.i_time_weekdays_lbl.grid(row = 0, column = k + 1)
for i in range(5):
for a in range(8):
b = c + datetime.timedelta(minutes = (30 * a))
d = b + datetime.timedelta(minutes = (30))
bttn_i_a = Button(self, text = "available",command = lambda: self.OpenPage(b.time().strftime('%H:%M'),d.time().strftime('%H:%M')))
bttn_i_a.grid(row = i + 1, column = a + 1)
bttn_i_a.config(height = 2, width = 10)
def timetable_button_gen_weekends(self):
c = datetime.datetime(100,1,1,10,00,00)
self.Saturday_lbl = Label(self, text = "Saturday")
self.Saturday_lbl.grid(row = 8, column = 0)
self.Sunday_lbl = Label(self, text = "Sunday")
self.Sunday_lbl.grid(row = 9, column = 0)
self.weekend_lbl = Label(self, text = "Weekend")
self.weekend_lbl.grid(row = 6, column = 1, sticky = W)
for k in range(10):
b = c + datetime.timedelta(minutes = (30 * k))
d = b + datetime.timedelta(minutes = (30))
self.i_time_weekdays_lbl = Label(self, text = b.time().strftime('%H:%M')+" to "+d.time().strftime('%H:%M'))
self.i_time_weekdays_lbl.grid(row = 7, column = k + 1)
for i in range(2):
for a in range(10):
b = c + datetime.timedelta(minutes = (30 * a))
d = b + datetime.timedelta(minutes = (30))
bttn_i_a = Button(self, text = "available",command = lambda: self.OpenPage(b.time().strftime('%H:%M'),d.time().strftime('%H:%M')))
bttn_i_a.grid(row = i + 8, column = a + 1)
bttn_i_a.config(height = 2, width = 10)
def OpenPage(self,startime,finishtime):
file = open("PassTimes.txt","w")
file.write(startime)
file.write("\n")
file.write(finishtime)
print(startime)
print(finishtime)
filepath = "PresentStudent.py"
global_namespace = {"__file__": filepath, "__name__": "__main__"}
with open(filepath, 'rb') as file:
exec(compile(file.read(), filepath, 'exec'), global_namespace)
root = Tk()
root.title("test")
root.geometry("2000x2000")
app = Application(root)
root.mainloop()
Welcome to SO.
General
IMHO, running the main routine of "PresentStudent.py" does not look that clean.
It works, but a main routine is built for when the script is called directly, not when it is imported and used in some other script.
Are you aware of the modules functionality in python?
I would recommend creating a function in PresentStudent.py that does what you are doing inside your main routine. Give the function parameters to pass the .txt-Filename.
e.g.
def presentStudentCall(inputFile):
and use it inside your script like:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# here we import PresentStudent.py, as we import it __main__ will not run
import PresentStudent
#[...]
def OpenPage(self, stime, etime):
#[...]
# Instead of executing a file we call the function from the module
PresentStudent.presentStudentCall(file)
If you want to display the data inside a second frame, you could also declare a class in PresentStudent.py and use it like:
def OpenPage(self, stime, etime):
#[...]
student=PresentStudent.Student() # assuming to name the class "Student"
student.presentStudentCall(file)
Your question itself
using the lambda does not need to be the best way. In matters of scope and garbage collecting your code only passes the last generated "b"s and "c"s to the definition.
What you could do to make it work is calculating the sender item in OpenPage:
To achieve that, I recommend having arrays for your time spans storing starting times.
Like
c = datetime.datetime(100,1,1,16,00,00)
self.weektimes = ["%s"%(c+datetime.timedelta(minutes=30*k)) for k in range(8)]
self.weekendtimes = ["%s"%((c+datetime.timedelta(minutes=30*k)) for k in range(10)]
First you need to bind the click event to the widget(in that case your button)
bttn_i_a.bind("<Button-1>", self.OnPage)
Your OpenPage could then look like this:
def OpenPage(self, event):
import time
# With that, we get the row and column where we clicked in
grid_info=event.widget.grid_info()
# week or weekend?
if grid_info["row"] > 5: #may depend on amount of headers
_timearray=self.weekendtimes
else:
_timearray=self.weektimes
# get the column
col=grid_info["column"]
# get the startTime
stime=_timearray[col]
# end time is +30 minutes
etime="%s"%(time.strptime("%s"%stime, "%H:%M")+time.struct_time(tm_min=30))
# now call the handler...

Categories

Resources