I have this code which is used to store information about a users account. Each account has its own record in a database. There is a field in each record which stores the variable Exercises. As each user performs multiple exercises this needs to be a list of different values. To do this is I have created a button which when clicked creates another entry box to input the exercise into. However as this list of entry are all under the same name I am having trouble storing the data held in every box. This is the code
global MemberID
intMemberID = MemberID
self.ent_MemberID = Entry(self.FrameExercise, bg = "PaleTurquoise1", font =("Arial","16"), width = 20, text = MemberID)
self.ent_MemberID.grid(row = 11, column = 12)
self.ent_MemberID.insert(END, intMemberID) #no "\n"
global ExerciseCount
ExerciseCount = 0
global WeightCount
WeightCount = 0
connection = sqlite3.connect(r"F:\Program\Accounts.db")
cursor = connection.cursor()
cursor.execute("SELECT * FROM Exercises WHERE MemberID=?", (MemberID,))#comma
def new(self):
global ExerciseCount
ExerciseCount = ExerciseCount + 1
print (ExerciseCount)
for num in range(ExerciseCount):
self.Exercises = Entry(self.FrameExercise, bg = "PaleTurquoise1", font =("Arial","16"), width = 20)
self.Exercises.grid(row=2+ExerciseCount, column=1)
global WeightCount
WeightCount = WeightCount + 1
print (WeightCount)
for num in range(WeightCount):
self.Weights = Entry(self.FrameExercise, bg = "PaleTurquoise1", font =("Arial","16"), width = 4)
self.Weights.grid(row=2+WeightCount, column=2)
def Update(self):
connection = sqlite3.connect(r"F:\Program\Accounts.db")
cursor = connection.cursor()
Exercise = self.Exercises.get()
Weight = self.Weights.get()
global MemberID
List = [Exercise, Weight, MemberID]
cursor.executemany("UPDATE Exercises SET Exercise=?, Weight=? WHERE MemberID=?",(Exercise, Weight, MemberID))
connection.commit()
When I create 2 entry boxes this is the error:
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 3, and there are 1 supplied
exercises should be stored in a separate exercise table that is tied to the member with a foreign key relationship on MemberID. Then write as many exercises as you want tied to the same member
Related
Alrighty, so I have 3 total functions defined in the project, but when I use the delete command, it will not refresh the other function to show the update to the rows, but when I use the submit command it does refresh. Any Advice? Main goal is that first my_delete(), I included the submit() as that one is correctly updating the show().
Little function to clearly pull information from the database for active trades, seperating the proper information to the columns and rows
def my_delete(self,id):
my_var=tkinter.messagebox.askyesnocancel("DELETE?", "Delete id:"+str(id),icon='warning',default="no")
if my_var:
r_set=c.execute("DELETE FROM openPositions WHERE s_id=" + str(id) )
conn.commit()
tkinter.messagebox.showerror("Deleted ","No of records deleted=" +str(r_set.rowcount))
self.show()
def show(self):
r_set=c.execute("SELECT * FROM openPositions")
i=6
for openPositions in r_set:
for j in range(len(openPositions)):
e = Label(self.master, width=10, text=(openPositions[j]), font=("Helvetica", 12))
e.grid(row=i, column = j + 1, padx=(70,0), pady=(5,0), columnspan=1)
### Close position button to populate for every trade ###
e = Button(self.master, text="Close Position", width=30, command=lambda d=openPositions[0] : self.my_delete(d))
e.grid(row=i, column = 6, padx=(10,0), pady=(5,0), columnspan=3)
i=i+1 # increments for each to next row
### Function for when Button is Pressed ###
def submit(self):
### convert string values to a new variable ##
stk = self.varStk.get()
typ = self.varType.get()
## changing quan and etrPr from string to integer and float values for multiplication ##
quan = int(self.varQuan.get())
entPr = float(self.varEnPr.get())
## multiplying quan and entPr to give us the Position Size for database and submitted text ##
posSize = quan * entPr
## Clearing entered data and resetting drop down menu to buy once button is clicked ##
self.txtStkTik.delete(0, END)
self.txtpos_quan.delete(0, END)
self.txtpos_price.delete(0, END)
self.varType.set("Buy")
## setting variables into an array for easy submitting to database ##
array1 = [stk,typ,quan,entPr,posSize]
## connecto to database and inserting array of variables into database ##
conn.executemany('INSERT INTO openPositions(stock_ticker, entryType, pos_quan, entryPrice, pos_size) VALUES (?,?,?,?,?)', (array1,))
conn.commit()
## pop up message displaying that commit of stock was completed ##
tkinter.messagebox.showinfo("Trade Submitted.", "You submitted {} for {} order in amount of {} share at an entry price of ${} for a total Position Size of ${}".format(stk,typ,quan,entPr,posSize))
#### Copied over the function for writing the information on screen to auto populate info when clicking submit instead of refreshing the app ###
self.show()
I have the following bits of code that creates a toplevel window and parses a dictionary into a Text widget:
def escrito(**kwargs):
write_window = Toplevel(root)
#write_window.title(kwargs) (problematic code)
writing_box = tk.Text(write_window, font = ("calibri", 20), width = 60, height = 15, wrap=WORD)
writing_box.pack(expand = tk.YES, fill = tk.X)
writing_box.grid(row = 0, column = 0, sticky = 'nswe')
texto = '\n'.join(key + ":\n" + value for key, value in kwargs.items())
writing_box.insert("1.0", texto)
def septic_osteo():
escrito(**infections.Septic_arthritis)
Septic_arthritis = {
'Empirical Treatment':
'Flucloxacillin 2g IV 6-hourly',
'If non-severe penicillin allergy':
'Ceftriaxone IV 2g ONCE daily',
'If severe penicillin allergy OR if known to be colonised with
MRSA':
'Vancomycin infusion IV, Refer to Vancomycin Prescribing
Policy',
'If systemic signs of sepsis': 'Discuss with Consultant
Microbiologist'
}
So when I run the code, the escrito functions parses the dictionary and writes its content onto a text widget contained on a Toplevel window. What I would like to know is how to dynamically rename the Toplevel window with the dicitonary's name. I do know that I can do this:
def septic_osteo():
escrito(**infections.Septic_arthritis)
write_window.title('Septic_arthritis)
but I do have like 100 functions like the one above, so, aside from labour intensive, I am not sure is the more pythonic way, so, is there a way that the window can be renamed with the dictionary name? (i.e. 'Septic_arthritis)
Thanks
If your data is in an object named infections, with attributes such as Septic_arthritis, the most straight-forward solution is to pass the data and the attribute as separate arguments, and then use getattr to get the data for the particular infection.
It would look something like this:
def escrito(data, infection):
write_window = Toplevel(root)
write_window.title(infection)
writing_box = tk.Text(write_window, font = ("calibri", 20), width = 60, height = 15, wrap="word")
writing_box.pack(expand = tk.YES, fill = tk.X)
writing_box.grid(row = 0, column = 0, sticky = 'nswe')
texto = '\n'.join(key + ":\n" + value for key, value in getattr(data, infection).items())
writing_box.insert("1.0", texto)
The important bit about the above code is that it uses getattr(data, infection) to get the data for the given infection.
If you want to create a button to call this function, it might look something like this:
button = tk.Button(..., command=lambda: escrito(infections, "Septic_arthritis"))
This will call the command escrito with two arguments: the object that contains all of the infections, and the key to the specific piece of information you want to display.
When I click show password it shows password but when I input 1 more letter in the entry box then that letter doesn't show up but when I input one more letter the previous letter shows up but the letter which I inputed just now doesn't show up So I want the code to update the password in the Show password label(show) in real time.
Code:
from tkinter import *
win = Tk()
no=2
def evod():
global no
no+=1
def showpwd(e):
global no, t
def bind():
text1=t.get()
btn2=Button(win, text="hide",command=hide)
btn2.grid(row=0,column=1)
show.config(text=text1)
evod()
def hide():
show.config(text="")
btn3=Button(win, text="show",command=bind)
btn3.grid(row=0,column=1)
evod()
if no % 2==0:
txt=t.get()
btn2=Button(win, text="hide",command=hide)
btn2.grid(row=0,column=1)
show.config(text=txt)
else:
show.config(text="")
btn=Button(win, text="show",command=bind)
btn.grid(row = 0, column = 1)
def bind():
show.config(text=t.get())
ent.bind("<Key>", showpwd)
t = StringVar()
ent = Entry(win,show="*", textvariable=t)
ent.grid(row = 0, column = 0)
btn=Button(win, text="show",command=bind)
btn.grid(row = 0, column = 1)
show= Label(win,text="")
show.grid(row = 1, column = 0,sticky="w")
win.mainloop()
I'm making a small GUI application that deals with grades and whatnot and outputs the highest grades and etc.
Here's a part of the code:
root = Tk()
gradeList = []
def addGradeObject(name, percentage):
gradeList.append(Grade(name, percentage))
updateOutput()
print(gradeList)
def undoAdd():
try:
gradeList.pop(len(gradeList) - 1)
updateOutput()
print(gradeList)
except Exception:
pass
def updateOutput():
highestGrade.setText(highest_grade(gradeList))
lowestGrade.setText(lowest_grade(gradeList))
numFailed.setText(num_failed(gradeList))
addButton = Button(text = "Add Grade", command = lambda: addGradeObject (entryA.get(), entryB.get())).grid(row = 1, column = 4)
undoButton = Button(text = "Undo", command = undoAdd).grid(row = 2, column = 4)
entryA = Entry()
entryA.grid(row = 1, column = 1)
entryB = Entry()
entryB.grid(row = 1, column = 2)
highestGrade = Entry()
highestGrade.grid(row = 2, column = 1)
lowestGrade = Entry()
lowestGrade.grid(row = 3, column = 1)
numFailed = Entry()
numFailed.grid(row = 4, column = 1)
root.title("Grade Checker")
root.mainloop()
The problem is I'm getting this error:
AttributeError: 'Entry' object has no attribute 'setText'
I don't understand. When you create an Entry box, doesn't the object of class "Entry" have an attribute/method that allows you to set text to it? I really don't know why it's not working
Entry methods can be found here. As far as I can tell, there is no setText method. There is however an insert method that you could use to set the text (though you might wand to delete the current text first).
def set_text(entry, text):
entry.delete(0, tkinter.END)
entry.insert(0 text)
Alternatively, you can hook the entry up to a StringVar and use it's .set() and .get() methods. e.g. (from the linked docs above):
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
I am new to python and recently i make dictionary using Python and Sqlite3 with tkinter.
When I run the code it returns multiple line in IDLE but in the GUI its only display the last result. I would like to display all the information in the GUI. Thanks you for any help and suggestion.
import tkinter
import sqlite3
class Dictionary:
def __init__(self,master =None):
self.main_window = tkinter.Tk()
self.main_window.title("Lai Mirang Dictionary")
self.main_window.minsize( 600,400)
self.main_window.configure(background = 'paleturquoise')
self.frame1 = tkinter.Frame()
self.frame2= tkinter.Frame(bg = 'red')
self.frame3 =tkinter.Text( foreground = 'green')
self.frame4 = tkinter.Text()
self.lai_label = tkinter.Label(self.frame1,anchor ='nw',font = 'Times:12', text = 'Lai',width =25,borderwidth ='3',fg='blue')
self.mirang_label = tkinter.Label(self.frame1,anchor ='ne',font = 'Times:12', text = 'Mirang',borderwidth ='3',fg ='blue')
self.lai_label.pack(side='left')
self.mirang_label.pack(side = 'left')
self.kawl_buttom= tkinter.Button(self.frame2 ,fg = 'red',font = 'Times:12',text ='Kawl',command=self.dic,borderwidth ='3',)
self.lai_entry = tkinter.Entry(self.frame2, width= 28, borderwidth ='3',)
self.lai_entry.focus_force()
self.lai_entry.bind('<Return>', self.dic,)
self.lai_entry.configure(background = 'khaki')
self.lai_entry.pack(side='left')
self.kawl_buttom.pack(side = 'left')
self.value = tkinter.StringVar()
self.mirang_label= tkinter.Label(self.frame3,font = 'Times:12',fg = 'blue',textvariable = self.value,justify = 'left',wraplength ='260',width = 30, height = 15,anchor = 'nw')
self.mirang_label.pack()
self.mirang_label.configure(background = 'seashell')
self.copyright_label = tkinter.Label(self.frame4,anchor ='nw',font = 'Times:12:bold',text = "copyright # cchristoe#gmail.com",width = 30,borderwidth = 3, fg = 'purple',)
self.copyright_label.pack()
self.frame1.pack()
self.frame2.pack()
self.frame3.pack()
self.frame4.pack()
tkinter.mainloop()
self.main_window.quit()
def dic(self, event = None):
conn = sqlite3.connect('C:/users/christoe/documents/sqlite/laimirangdictionary.sqlite')
c = conn.cursor()
kawl = self.lai_entry.get()
kawl = kawl + '%'
c.execute("SELECT * FROM laimirang WHERE lai LIKE ?", (kawl,))
c.fetchall
for member in c:
out = (member)
self.value.set(out)
print(out, )
dic=Dictionary()
You need to change:
c.execute("SELECT * FROM laimirang WHERE lai LIKE ?", (kawl,))
c.fetchall
for member in c:
out = (member)
self.value.set(out)
print(out, )
To:
for member in c.execute("SELECT * FROM laimirang WHERE lai LIKE ?", (kawl,)):
current_text = self.value.get()
new_text = current_text +( "\n" if current_text else "") +" ".join(member)
self.value.set(new_text)
The new version gets the current value of the StringVar value and then appends the results returned with a space inbetween for each row returned with each row on its own line. What you were doing however involved just updating the StringVar to be the current member object, and therefore it only ever had the last values.
This is how it looks with more than one line: