Posts: 22
Threads: 6
Joined: Jun 2021
I have a program that records score when practicing darts, then shows them in a high score table.
def addToDb(self):
name = self.name
total = self.runningTotal
connection = sqlite3.connect('highscores.db')
cur = connection.cursor()
insert_statement = ''' INSERT INTO finisheshigh(playername, score) VALUES(?, ?); '''
insert_values = (name, total)
cur.execute(insert_statement, insert_values)
print("done")
connection.commit()
cur.close() I have this code which adds the result to the database.
And this code displays it.
connection = sqlite3.connect('highscores.db')
cur = connection.cursor()
connection.commit()
# populate rtb table
read_query = '''SELECT * FROM rtbhigh ORDER BY score DESC'''
cur.execute(read_query)
items = cur.fetchall()
tk.Label(frame1, text="Round the board").grid(row=0,column=0, columnspan=3)
row = 1
buttonnumber = 1
for item in items:
fullframe = tk.Frame(frame1, highlightbackground="black", highlightthickness=1)
fullframe.grid(row=row, column=0)
tk.Label(fullframe, text=buttonnumber).grid(row=0, column=0)
tk.Label(fullframe, text=item[0], width=20).grid(row=0, column=1)
tk.Label(fullframe, text=item[1]).grid(row=0, column=2)
row += 1
buttonnumber +=1
#populate finishes table
read_query = '''SELECT * FROM finisheshigh'''
cur.execute(read_query)
items = cur.fetchall()
tk.Label(frame2, text="Finishes").grid(row=0,column=0, columnspan=3)
row = 1
buttonnumber = 1
for item in items:
fullframe = tk.Frame(frame2, highlightbackground="black", highlightthickness=1)
fullframe.grid(row=row, column=0)
tk.Label(fullframe, text=buttonnumber).grid(row=0, column=0)
tk.Label(fullframe, text=item[0], width=20).grid(row=0, column=1)
tk.Label(fullframe, text=item[1]).grid(row=0, column=2)
row += 1
buttonnumber +=1
connection.commit()
cur.close() The issue I am having is the result which has just been input does not show in the displayed table, if the program is shut down then restarted it is there.
I have tried both cur.close and connection.close with no success.
Any help would be greatly appreciated.
Posts: 1,145
Threads: 114
Joined: Sep 2019
May-24-2023, 06:42 PM
(This post was last modified: May-24-2023, 06:42 PM by menator01.)
I took the liberty of giving your code a try. There is no data validation but, is a working model using classes. This could be improved upon.
import tkinter as tk
import sqlite3 as sq
class Database:
'''
Database class handles all database functions.
Connects, creates, inserts, and get data
'''
def __init__(self):
''' Set some instance variables '''
self.table = 'finisheshigh'
self.connection = sq.connect('highscores.db')
self.cursor = self.connection.cursor()
def create(self):
''' Method for creating the table '''
self.cursor.execute(f'''
create table if not exists {self.table} (
id integer primary key,
playername text,
score integer
)
''')
self.connection.commit()
def insert(self, playername, score):
''' Method for inserting data '''
self.cursor.execute(f'''
insert into {self.table} (playername, score)
values (?, ?)''', (playername, score))
self.connection.commit()
def getall(self):
''' Method for getting data '''
self.cursor.execute(f'select * from {self.table} order by score desc')
return self.cursor.fetchall()
class Window:
'''
Window class sets up the main window view
'''
def __init__(self, parent):
self.parent = parent
parent.columnconfigure(0, weight=1)
parent.rowconfigure(0, weight=1)
self.container = tk.Frame(parent)
self.container.grid(column=0, row=0, sticky='news', padx=5, pady=5)
self.container.grid_columnconfigure(0, weight=3, uniform='columns')
self.container.grid_columnconfigure(1, weight=3, uniform='columns')
header = tk.Label(self.container, text='Player', bg='lightgray')
header['font'] = (None, 16, 'bold')
header['relief'] = 'groove'
header.grid(column=0, row=0, sticky='new', padx=(5,0), pady=(5,1))
header2 = tk.Label(self.container, text='Score', bg='lightgray')
header2['font'] = (None, 16, 'bold')
header2['relief'] = 'groove'
header2.grid(column=1, row=0, sticky='new', padx=(2,3), pady=(5,1))
self.data_container = tk.Frame(self.container)
self.data_container['relief'] = 'groove'
self.data_container.grid(column=0, columnspan=2, row=1, sticky='new', padx=5, pady=(1,5))
self.data_container.grid_columnconfigure(0, weight=3, uniform='columns')
self.data_container.grid_columnconfigure(1, weight=3, uniform='columns')
self.data_container.grid_columnconfigure(0, weight=3, uniform='data')
self.data_container.grid_columnconfigure(1, weight=3, uniform='data')
self.button = tk.Button(self.container, text='Add Entry')
self.button['font'] = (None, 12, 'bold')
self.button['cursor'] = 'hand2'
self.button.grid(column=0, columnspan=2, row=3, ipadx=2, ipady=2)
class Form:
''' Form class builds and displays the form in a toplevel window '''
def __init__(self, parent, getall):
self.parent = parent
self.getall = getall
self.window = tk.Toplevel(None)
self.window['padx'] = 10
self.window['pady'] = 5
self.window.title('Data Form')
self.name = tk.StringVar()
self.score = tk.StringVar()
label = tk.Label(self.window, text='Name:', font=(None, 14, 'bold'))
label.grid(column=0, row=0, sticky='new', pady=2)
name = tk.Entry(self.window, textvariable=self.name, font=(None, 14, 'normal'))
name.grid(column=1, row=0, sticky='new')
label = tk.Label(self.window, text='Score:', font=(None, 14, 'bold'))
label.grid(column=0, row=1, sticky='new', pady=2)
score = tk.Entry(self.window, textvariable=self.score, font=(None, 14, 'normal'))
score.grid(column=1, row=1, sticky='new')
button = tk.Button(self.window, text='Submit', font=(None, 12, 'normal'))
button['command'] = lambda: self.insert(self.name, self.score)
button.grid(column=0, columnspan=2, row=2)
self.window.protocol('WM_DELETE_WINDOW', self.close)
def insert(self, name, score):
''' Method that inserts the data '''
Database().insert(name.get(), score.get())
self.close()
def close(self):
''' A way to close the toplevel window and reopen the main window '''
self.window.destroy()
self.getall()
self.parent.deiconify()
class Controller:
'''
Controller class communicates between the classes
'''
def __init__(self, database, window):
# Set instance variables and populate the window if data exists
self.database = database
self.database.create()
self.window = window
self.getall()
# Command for the window button to open toplevel window
self.window.button['command'] = self._window
def _window(self):
''' Method for withdrawing main window and opoening toplevel window '''
self.window.parent.withdraw()
form = Form(self.window.parent, self.getall)
def getall(self):
'''
This method could be improved on
'''
stats = self.database.getall() # Get database entries
# This will destroy and rebuild the data container in the main window.
# Reasoning was that trace data was still visible after entering data
self.window.data_container.destroy()
self.window.data_container = tk.Frame(self.window.container)
self.window.data_container['relief'] = 'groove'
self.window.data_container.grid(column=0, columnspan=2, row=1, sticky='new', padx=5, pady=(1,5))
self.window.data_container.grid_columnconfigure(0, weight=3, uniform='columns')
self.window.data_container.grid_columnconfigure(1, weight=3, uniform='columns')
self.window.data_container.grid_columnconfigure(0, weight=3, uniform='data')
self.window.data_container.grid_columnconfigure(1, weight=3, uniform='data')
# if there is no data display a message stating so else populate
if not stats:
label = tk.Label(self.window.data_container)
label['text'] = 'Currently, there are not any stats recorded.'
label['fg'] = 'red'
label['font'] = (None, 14, 'normal')
label['relief'] = 'ridge'
label.grid(column=0, columnspan=2, row=0, sticky='new', ipadx=5)
else:
for row, data in enumerate(self.database.getall()):
label = tk.Label(self.window.data_container)
label['font'] = (None, 14, 'normal')
label['text'] = data[1].title()
label['relief'] = 'ridge'
label.grid(column=0, row=row, sticky='new', padx=(0,1), pady=2)
label = tk.Label(self.window.data_container)
label['font'] = (None, 14, 'normal')
label['text'] = data[2]
label['relief'] = 'ridge'
label.grid(column=1, row=row, sticky='new', padx=(1,0), pady=2)
if __name__ == '__main__':
root = tk.Tk()
controller = Controller(Database(), Window(root))
root.mainloop()
Posts: 22
Threads: 6
Joined: Jun 2021
(May-24-2023, 04:37 AM)angus1964 Wrote: I have a program that records score when practicing darts, then shows them in a high score table.
def addToDb(self):
name = self.name
total = self.runningTotal
connection = sqlite3.connect('highscores.db')
cur = connection.cursor()
insert_statement = ''' INSERT INTO finisheshigh(playername, score) VALUES(?, ?); '''
insert_values = (name, total)
cur.execute(insert_statement, insert_values)
print("done")
connection.commit()
cur.close() I have this code which adds the result to the database.
And this code displays it.
connection = sqlite3.connect('highscores.db')
cur = connection.cursor()
connection.commit()
# populate rtb table
read_query = '''SELECT * FROM rtbhigh ORDER BY score DESC'''
cur.execute(read_query)
items = cur.fetchall()
tk.Label(frame1, text="Round the board").grid(row=0,column=0, columnspan=3)
row = 1
buttonnumber = 1
for item in items:
fullframe = tk.Frame(frame1, highlightbackground="black", highlightthickness=1)
fullframe.grid(row=row, column=0)
tk.Label(fullframe, text=buttonnumber).grid(row=0, column=0)
tk.Label(fullframe, text=item[0], width=20).grid(row=0, column=1)
tk.Label(fullframe, text=item[1]).grid(row=0, column=2)
row += 1
buttonnumber +=1
#populate finishes table
read_query = '''SELECT * FROM finisheshigh'''
cur.execute(read_query)
items = cur.fetchall()
tk.Label(frame2, text="Finishes").grid(row=0,column=0, columnspan=3)
row = 1
buttonnumber = 1
for item in items:
fullframe = tk.Frame(frame2, highlightbackground="black", highlightthickness=1)
fullframe.grid(row=row, column=0)
tk.Label(fullframe, text=buttonnumber).grid(row=0, column=0)
tk.Label(fullframe, text=item[0], width=20).grid(row=0, column=1)
tk.Label(fullframe, text=item[1]).grid(row=0, column=2)
row += 1
buttonnumber +=1
connection.commit()
cur.close() The issue I am having is the result which has just been input does not show in the displayed table, if the program is shut down then restarted it is there.
I have tried both cur.close and connection.close with no success.
Any help would be greatly appreciated.
Hi Menator thats very helpful. You are correct about the data validation, I was hoping to get the basics working before looking at the bells and whistles.
Here is the full code.
import tkinter as tk
from tkinter import ttk
import sqlite3
class practice(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# Adding a title to the window
self.wm_title("Test Application")
# creating a frame and assigning it to container
container = tk.Frame(self, height=400, width=600)
# specifying the region where the frame is packed in root
container.pack(side="top", fill="both", expand=True)
# configuring the location of the container using grid
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.menu = tk.Menu(container, bg="lightgrey", fg="black")
# first menu item
self.game_menu = tk.Menu(self.menu, tearoff=0, bg="lightgrey", fg="black")
self.game_menu.add_command(label="New Game", command=lambda: self.show_frame(RtbPage),)
self.menu.add_cascade(label="Round the board", menu=self.game_menu)
# second menu item
self.stat_menu = tk.Menu(self.menu, tearoff=0, bg="lightgrey", fg="black")
self.stat_menu.add_command(label="New Game", command=lambda: self.show_frame(FinishesPage))
self.menu.add_cascade(label="Finishes", menu=self.stat_menu)
# third menu item
self.stat_menu = tk.Menu(self.menu, tearoff=0, bg="lightgrey", fg="black")
self.stat_menu.add_command(label="High Scores", command=lambda: self.show_frame(HighScoresPage))
self.menu.add_cascade(label="High Scores", menu=self.stat_menu)
# populate the menu
self.config(menu=self.menu)
# We will now create a dictionary of frames
self.frames = {}
# we'll create the frames themselves later but let's add the components to the dictionary.
for F in (StartPage, RtbPage, FinishesPage, HighScoresPage):
frame = F(container, self)
# the windows class acts as the root window for the frames.
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
# Using a method to switch frames
self.show_frame(StartPage)
self.db_connect()
def show_frame(self, cont):
frame = self.frames[cont]
# raises the current frame to the top
frame.tkraise()
def db_connect(self):
connection = sqlite3.connect('highscores.db')
cur = connection.cursor()
try:
cur.execute('SELECT * FROM rtbhigh')
except sqlite3.OperationalError:
cur.execute(''' CREATE TABLE rtbhigh(playername text, score integer) ''')
cur.execute(''' CREATE TABLE finisheshigh(playername text, score integer) ''')
connection.commit()
cur.close()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Main Page")
label.pack(padx=10, pady=10)
class RtbPage(tk.Frame):
def __init__(self, parent, controller ):
tk.Frame.__init__(self, parent)
#variables
self.playerName = tk.StringVar()
self.toGoFor = 1
self.runningTotal = 0
self.goFor = tk.IntVar()
self.goFor.set(self.toGoFor)
self.running = tk.IntVar()
self.running.set(self.runningTotal)
frame1 = tk.Frame(self)
frame1.grid(row=0, column=0, sticky='nsew')
namelabel = tk.Label(frame1, text="Player Name: ")
namelabel.grid(row=0, column=0, sticky='ew')
nameEntry = tk.Entry(frame1, textvariable=self.playerName)
nameEntry.grid(row=0, column=1, sticky='ew')
startButton = tk.Button(frame1, text="Start", command=self.show_frame2)
startButton.grid(row=0, column=2, sticky='ew')
def show_frame2(self):
self.name = self.playerName.get()
frame2 = tk.Frame(self)
frame2.grid(row=1, column=0, sticky='nsew')
togoforLabel = tk.Label(frame2, text="To Go For:")
togoforLabel.grid(row=0, column=0, sticky='nsew')
numberLabel = tk.Label(frame2, textvariable=self.goFor)
numberLabel.grid(row=1, column=0, sticky='nsew')
hitLabel = tk.Label(frame2, text="Enter Number Hit:")
hitLabel.grid(row=0, column=1)
self.hitCombo = ttk.Combobox(frame2, width = 15)
self.hitCombo.grid(row=1, column=1, sticky='nsew')
self.hitCombo['values'] = (0, 1, 2, 3,4,5,6, 7,8,9)
#self.hitCombo.bind('<<ComboboxSelected>>', self.score_entered)
self.hitCombo.bind('<Return>', self.score_entered)
scoreButton = tk.Button(frame2, text=" Enter: ", command=self.score_entered)
scoreButton.grid(row=2, column=1)
totalLabel = tk.Label(frame2, text="Running Total : ")
totalLabel.grid(row=0, column=2, sticky='nsew')
runningLabel = tk.Label(frame2, textvariable=self.running)
runningLabel.grid(row=1, column=2, sticky='nsew')
def score_entered(self):
score = int(self.hitCombo.get())
subTotal = score * self.toGoFor
self.runningTotal += subTotal
self.toGoFor += 1
if self.toGoFor == 21:
self.toGoFor = 25
if self.toGoFor == 5:
self.running.set(self.runningTotal)
self.gameFinished()
else:
self.goFor.set(self.toGoFor)
self.running.set(self.runningTotal)
self.hitCombo.set('')
def gameFinished(self):
frame3 = tk.Frame(self)
frame3.grid(row=2, column=0, sticky='nsew')
overLabel = tk.Label(frame3, text="Game Over: Your Total is: ")
overLabel.grid(row=0, column=0, sticky='nsew')
totalLabel = tk.Label(frame3, textvariable=self.running)
totalLabel.grid(row=0, column=1, sticky='nsew')
saveButton = tk.Button(frame3, text="Save", command=self.addToDb)
saveButton.grid(row=0, column=2, sticky='nsew')
def addToDb(self):
name = self.name
total = self.runningTotal
connection = sqlite3.connect('highscores.db')
cur = connection.cursor()
insert_statement = ''' INSERT INTO rtbhigh(playername, score) VALUES(?, ?); '''
insert_values = (name, total)
cur.execute(insert_statement, insert_values)
print("done")
connection.commit()
cur.close()
class FinishesPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
#variables
self.toGoFor = 61
self.runningTotal = 0
self.goFor = tk.IntVar()
self.goFor.set(self.toGoFor)
self.running = tk.IntVar()
self.running.set(self.runningTotal)
self.playerName = tk.StringVar()
frame1 = tk.Frame(self)
frame1.grid(row=0, column=0, sticky='nsew')
namelabel = tk.Label(frame1, text="Player Name: ")
namelabel.grid(row=0, column=0, sticky='ew')
nameEntry = tk.Entry(frame1, textvariable=self.playerName)
nameEntry.grid(row=0, column=1, sticky='ew')
startButton = tk.Button(frame1, text="Start", command=self.show_frame2)
startButton.grid(row=0, column=2, sticky='ew')
def show_frame2(self):
self.name = self.playerName.get()
frame2 = tk.Frame(self)
frame2.grid(row=1, column=0, sticky='nsew')
togoforLabel = tk.Label(frame2, text="To Go For:")
togoforLabel.grid(row=0, column=0, sticky='nsew')
numberLabel = tk.Label(frame2, textvariable=self.goFor)
numberLabel.grid(row=1, column=0, sticky='nsew')
hitLabel = tk.Label(frame2, text="Number of darts used:")
hitLabel.grid(row=0, column=1)
self.hitCombo = ttk.Combobox(frame2, width = 15)
self.hitCombo.grid(row=1, column=1, sticky='nsew')
self.hitCombo['values'] = (2,3,4,5,6,0)
self.hitCombo.bind('<<ComboboxSelected>>')
scoreButton = tk.Button(frame2, text=" Enter: ", command=self.score_entered)
scoreButton.grid(row=2, column=1)
totalLabel = tk.Label(frame2, text="Running Total : ")
totalLabel.grid(row=0, column=2, sticky='nsew')
runningLabel = tk.Label(frame2, textvariable=self.running)
runningLabel.grid(row=1, column=2, sticky='nsew')
def score_entered(self):
darts = int(self.hitCombo.get())
if self.toGoFor == 99:
if darts == 0:
self.runningTotal += 0
elif darts == 3:
self.runningTotal += 3
elif darts == 4 or 5 or 6:
self.runningTotal += 1
else:
if darts == 0:
self.runningTotal += 0
elif darts == 2:
self.runningTotal += 3
elif darts == 3:
self.runningTotal += 2
elif darts == 4 or 5 or 6:
self.runningTotal += 1
self.running.set(self.runningTotal)
self.toGoFor += 1
if self.toGoFor == 63:
self.gameFinished()
else:
self.goFor.set(self.toGoFor)
self.hitCombo.set('')
def gameFinished(self):
frame3 = tk.Frame(self)
frame3.grid(row=2, column=0, sticky='nsew')
overLabel = tk.Label(frame3, text="Game Over: Your Total is: ")
overLabel.grid(row=0, column=0, sticky='nsew')
tk.Label(frame3, text=self.runningTotal).grid(row=0,column=1, sticky='nsew')
saveButton = tk.Button(frame3, text="Save", command=self.addToDb)
saveButton.grid(row=0, column=2, sticky='nsew')
def addToDb(self):
name = self.name
total = self.runningTotal
connection = sqlite3.connect('highscores.db')
cur = connection.cursor()
insert_statement = ''' INSERT INTO finisheshigh(playername, score) VALUES(?, ?); '''
insert_values = (name, total)
cur.execute(insert_statement, insert_values)
print("done")
connection.commit()
cur.close()
class HighScoresPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
frame1 = tk.Frame(self)
frame1.grid(row=0, column=0, sticky='nsew')
frame2 = tk.Frame(self)
frame2.grid(row=0, column=1, sticky='nsew')
connection = sqlite3.connect('highscores.db')
cur = connection.cursor()
connection.commit()
# populate rtb table
read_query = '''SELECT * FROM rtbhigh ORDER BY score DESC'''
cur.execute(read_query)
items = cur.fetchall()
tk.Label(frame1, text="Round the board").grid(row=0,column=0, columnspan=3)
row = 1
buttonnumber = 1
for item in items:
fullframe = tk.Frame(frame1, highlightbackground="black", highlightthickness=1)
fullframe.grid(row=row, column=0)
tk.Label(fullframe, text=buttonnumber).grid(row=0, column=0)
tk.Label(fullframe, text=item[0], width=20).grid(row=0, column=1)
tk.Label(fullframe, text=item[1]).grid(row=0, column=2)
row += 1
buttonnumber +=1
#populate finishes table
read_query = '''SELECT * FROM finisheshigh'''
cur.execute(read_query)
items = cur.fetchall()
tk.Label(frame2, text="Finishes").grid(row=0,column=0, columnspan=3)
row = 1
buttonnumber = 1
for item in items:
fullframe = tk.Frame(frame2, highlightbackground="black", highlightthickness=1)
fullframe.grid(row=row, column=0)
tk.Label(fullframe, text=buttonnumber).grid(row=0, column=0)
tk.Label(fullframe, text=item[0], width=20).grid(row=0, column=1)
tk.Label(fullframe, text=item[1]).grid(row=0, column=2)
row += 1
buttonnumber +=1
connection.commit()
cur.close()
if __name__ == "__main__":
game = practice()
game.mainloop()
Posts: 1,145
Threads: 114
Joined: Sep 2019
I tried running your code, the database was created but not the tables.
Posts: 22
Threads: 6
Joined: Jun 2021
(May-24-2023, 06:42 PM)menator01 Wrote: I took the liberty of giving your code a try. There is no data validation but, is a working model using classes. This could be improved upon.
import tkinter as tk
import sqlite3 as sq
class Database:
'''
Database class handles all database functions.
Connects, creates, inserts, and get data
'''
def __init__(self):
''' Set some instance variables '''
self.table = 'finisheshigh'
self.connection = sq.connect('highscores.db')
self.cursor = self.connection.cursor()
def create(self):
''' Method for creating the table '''
self.cursor.execute(f'''
create table if not exists {self.table} (
id integer primary key,
playername text,
score integer
)
''')
self.connection.commit()
def insert(self, playername, score):
''' Method for inserting data '''
self.cursor.execute(f'''
insert into {self.table} (playername, score)
values (?, ?)''', (playername, score))
self.connection.commit()
def getall(self):
''' Method for getting data '''
self.cursor.execute(f'select * from {self.table} order by score desc')
return self.cursor.fetchall()
class Window:
'''
Window class sets up the main window view
'''
def __init__(self, parent):
self.parent = parent
parent.columnconfigure(0, weight=1)
parent.rowconfigure(0, weight=1)
self.container = tk.Frame(parent)
self.container.grid(column=0, row=0, sticky='news', padx=5, pady=5)
self.container.grid_columnconfigure(0, weight=3, uniform='columns')
self.container.grid_columnconfigure(1, weight=3, uniform='columns')
header = tk.Label(self.container, text='Player', bg='lightgray')
header['font'] = (None, 16, 'bold')
header['relief'] = 'groove'
header.grid(column=0, row=0, sticky='new', padx=(5,0), pady=(5,1))
header2 = tk.Label(self.container, text='Score', bg='lightgray')
header2['font'] = (None, 16, 'bold')
header2['relief'] = 'groove'
header2.grid(column=1, row=0, sticky='new', padx=(2,3), pady=(5,1))
self.data_container = tk.Frame(self.container)
self.data_container['relief'] = 'groove'
self.data_container.grid(column=0, columnspan=2, row=1, sticky='new', padx=5, pady=(1,5))
self.data_container.grid_columnconfigure(0, weight=3, uniform='columns')
self.data_container.grid_columnconfigure(1, weight=3, uniform='columns')
self.data_container.grid_columnconfigure(0, weight=3, uniform='data')
self.data_container.grid_columnconfigure(1, weight=3, uniform='data')
self.button = tk.Button(self.container, text='Add Entry')
self.button['font'] = (None, 12, 'bold')
self.button['cursor'] = 'hand2'
self.button.grid(column=0, columnspan=2, row=3, ipadx=2, ipady=2)
class Form:
''' Form class builds and displays the form in a toplevel window '''
def __init__(self, parent, getall):
self.parent = parent
self.getall = getall
self.window = tk.Toplevel(None)
self.window['padx'] = 10
self.window['pady'] = 5
self.window.title('Data Form')
self.name = tk.StringVar()
self.score = tk.StringVar()
label = tk.Label(self.window, text='Name:', font=(None, 14, 'bold'))
label.grid(column=0, row=0, sticky='new', pady=2)
name = tk.Entry(self.window, textvariable=self.name, font=(None, 14, 'normal'))
name.grid(column=1, row=0, sticky='new')
label = tk.Label(self.window, text='Score:', font=(None, 14, 'bold'))
label.grid(column=0, row=1, sticky='new', pady=2)
score = tk.Entry(self.window, textvariable=self.score, font=(None, 14, 'normal'))
score.grid(column=1, row=1, sticky='new')
button = tk.Button(self.window, text='Submit', font=(None, 12, 'normal'))
button['command'] = lambda: self.insert(self.name, self.score)
button.grid(column=0, columnspan=2, row=2)
self.window.protocol('WM_DELETE_WINDOW', self.close)
def insert(self, name, score):
''' Method that inserts the data '''
Database().insert(name.get(), score.get())
self.close()
def close(self):
''' A way to close the toplevel window and reopen the main window '''
self.window.destroy()
self.getall()
self.parent.deiconify()
class Controller:
'''
Controller class communicates between the classes
'''
def __init__(self, database, window):
# Set instance variables and populate the window if data exists
self.database = database
self.database.create()
self.window = window
self.getall()
# Command for the window button to open toplevel window
self.window.button['command'] = self._window
def _window(self):
''' Method for withdrawing main window and opoening toplevel window '''
self.window.parent.withdraw()
form = Form(self.window.parent, self.getall)
def getall(self):
'''
This method could be improved on
'''
stats = self.database.getall() # Get database entries
# This will destroy and rebuild the data container in the main window.
# Reasoning was that trace data was still visible after entering data
self.window.data_container.destroy()
self.window.data_container = tk.Frame(self.window.container)
self.window.data_container['relief'] = 'groove'
self.window.data_container.grid(column=0, columnspan=2, row=1, sticky='new', padx=5, pady=(1,5))
self.window.data_container.grid_columnconfigure(0, weight=3, uniform='columns')
self.window.data_container.grid_columnconfigure(1, weight=3, uniform='columns')
self.window.data_container.grid_columnconfigure(0, weight=3, uniform='data')
self.window.data_container.grid_columnconfigure(1, weight=3, uniform='data')
# if there is no data display a message stating so else populate
if not stats:
label = tk.Label(self.window.data_container)
label['text'] = 'Currently, there are not any stats recorded.'
label['fg'] = 'red'
label['font'] = (None, 14, 'normal')
label['relief'] = 'ridge'
label.grid(column=0, columnspan=2, row=0, sticky='new', ipadx=5)
else:
for row, data in enumerate(self.database.getall()):
label = tk.Label(self.window.data_container)
label['font'] = (None, 14, 'normal')
label['text'] = data[1].title()
label['relief'] = 'ridge'
label.grid(column=0, row=row, sticky='new', padx=(0,1), pady=2)
label = tk.Label(self.window.data_container)
label['font'] = (None, 14, 'normal')
label['text'] = data[2]
label['relief'] = 'ridge'
label.grid(column=1, row=row, sticky='new', padx=(1,0), pady=2)
if __name__ == '__main__':
root = tk.Tk()
controller = Controller(Database(), Window(root))
root.mainloop()
Hi Menator, did give your code a try and got the following error.
Quote:Traceback (most recent call last):
File "/Users/angusgalbraith/Library/CloudStorage/OneDrive-Personal/Programming/Darts/Python/web.py", line 181, in <module>
controller = Controller(Database(), Window(root))
File "/Users/angusgalbraith/Library/CloudStorage/OneDrive-Personal/Programming/Darts/Python/web.py", line 127, in __init__
self.getall()
File "/Users/angusgalbraith/Library/CloudStorage/OneDrive-Personal/Programming/Darts/Python/web.py", line 166, in getall
label['text'] = data[1].title()
AttributeError: 'int' object has no attribute 'title'
Will have a better look in the morning, lots of good things I will take from your code
Many Thanks
Angus
menator01 likes this post
Posts: 1,145
Threads: 114
Joined: Sep 2019
You can remove the .title() part. It just capitalizes the returned names
Posts: 22
Threads: 6
Joined: Jun 2021
(May-24-2023, 07:02 PM)menator01 Wrote: I tried running your code, the database was created but not the tables.
It worked OK on mine, will try running from scratch again tomorrow.
Posts: 22
Threads: 6
Joined: Jun 2021
(May-24-2023, 07:02 PM)menator01 Wrote: I tried running your code, the database was created but not the tables.
Hi Menator
I moved the call to create the db to just below menu creation, and it works fine now, not a great way to do it, will investigates your class method.
Still have the original issue, did wonder if it was due to files being on cloud but when run locally same issue. Hoping once class built it will solve it.
Have managed to work out when you click the save button it is added to the database, I checked from the terminal. So it would appear the issue is getting the full data to populate the table.
Posts: 12,038
Threads: 487
Joined: Sep 2016
SQLalchemy makes working with databases very straight forward and maintainable.
If interested, I have a tutorial (a bit old but should still be good) here.
Posts: 22
Threads: 6
Joined: Jun 2021
(May-25-2023, 10:16 PM)Larz60+ Wrote: SQLalchemy makes working with databases very straight forward and maintainable.
If interested, I have a tutorial (a bit old but should still be good) here.
Hi Larz
Will have a look at SQLalchemy, would be nice to know why I have the issue I have just in case I have made a fundamental mistake and just not realised.
|