UnboundLocalError: local variable 'qn' referenced before assignment - python

I'm getting the error "UnboundLocalError: local variable 'qn' referenced before assignment" on running the code. Why is that? How can I correct it? I'm new to tkinter so please try to keep it simple. This is part of the code for a game I was writing. It would be a great help if I could get an answer soon
from tkinter import *
from tkinter import messagebox
from io import StringIO
root = Tk()
root.title("Captain!")
root.geometry("660x560")
qn = '''1$who are you?$char1$i am joe$3$i am ben$2
2$what are you?$char2$i am a person$1$i am nobody$3
3$how are you?$char3$i am fine$2$i'm alright$1'''
var = '''1$10$-35$20$15$-20
2$9$7$30$-5$-15
3$10$-25$-15$10$5'''
class Game :
def __init__(self):
self.m_cur = {1:["Military",50]}
self.c_cur = {1:["People's",50]}
self.r_cur = {1:["Research",50]}
self.i_cur = {1:["Industrial",50]}
self.p_cur = {1:["Research",50]}
#function to clear all widgets on screen when called
def clear(self):
for widget in root.winfo_children():
widget.destroy()
#function to quit the window
def exit(self):
msg = messagebox.askquestion("Thank you for playing","Are you sure you want to exit?")
if msg == "yes" :
root.destroy()
else:
Game.main(self)
#start function
def start(self):
Label(root,text="Hello, what should we call you?",font=("segoe print",20)).grid(row=0,column=0)
name = Entry(root,width=20)
name.grid(row=1,column=0)
Button(root,text="Enter",font=("segoe print",20),command=lambda: Game.main(self)).grid(row=1,column=1)
self.name=name.get()
#main function
def main(self):
Game.clear(self)
Label(root,text="Welcome to the game",font=("segoe print",20)).grid(row=0,column=0)
Label(root,text='What do you want to do?',font=("segoe print",20)).grid(row=1,column=0)
Button(root,text="Start Game",font=("segoe print",20),command=lambda: Game.qn_func(self,1)).grid(row=2,column=0)
Button(root,text="Exit Game",font=("segoe print",20),command=lambda: Game.exit(self)).grid(row=3,column=0)
#function to check variables and display game over
def game_over(self,x_cur):
if x_cur[1][1]<=0 or x_cur[1][1]>=100 : #condition to check game over
Game.clear(self)
Label(root,text=x_cur)
Label(root,text="GAME OVER",font=("ariel",20)).place(relx=0.5,rely=0.5,anchor=CENTER)
Button(root,text="Continue",font=("segoe print",20),command=lambda: Game.main(self)).place(relx=0.5,rely=0.6)
#function to display question and variables
def qn_func(self,qn_num) :
Game.clear(self)
#accessing the questions
q_file = StringIO(qn)
#reading the question, options, next qn numbers and the character name from the file
qn_list = q_file.readlines()
qn = qn_list[qn_num-1].strip().split("$")[1]
char_name = qn_list[qn_num-1].strip().split("$")[2]
qn1 = qn_list[qn_num-1].strip().split("$")[3]
qn2 = qn_list[qn_num-1].strip().split("$")[5]
n_qn1 = int(qn_list[qn_num-1].strip().split("$")[4])
n_qn2 = int(qn_list[qn_num-1].strip().split("$")[6])
#displaying the character name and the question as a label frame widget with character name as parent
label_frame = LabelFrame(root,text = char_name,font = ("segoe print",20))
label = Label(label_frame,text = qn,font = ("segoe print",20))
label_frame.place(relx=0.5,rely=0.5,anchor=CENTER)
label.pack()
q_file.close()
#accessing variables
v_file = StringIO(var)
#reading values of variables from file
v_list = v_file.readlines()
self.r_cur[1][1] += int(v_list[qn_num-1].strip().split("$")[1])
self.c_cur[1][1] += int(v_list[qn_num-1].strip().split("$")[2])
self.i_cur[1][1] += int(v_list[qn_num-1].strip().split("$")[3])
self.m_cur[1][1] += int(v_list[qn_num-1].strip().split("$")[4])
self.p_cur[1][1] += int(v_list[qn_num-1].strip().split("$")[5])
#running each variable through game_over to see if you are dead
Game.game_over(self,self.r_cur)
Game.game_over(self,self.c_cur)
Game.game_over(self,self.i_cur)
Game.game_over(self,self.m_cur)
Game.game_over(self,self.p_cur)
#defining the Doublevar variables
s_var1 = DoubleVar()
s_var2 = DoubleVar()
s_var3 = DoubleVar()
s_var4 = DoubleVar()
s_var5 = DoubleVar()
#setting the values in the scales
s_var1.set(self.r_cur[1][1])
s_var2.set(self.c_cur[1][1])
s_var3.set(self.i_cur[1][1])
s_var4.set(self.m_cur[1][1])
s_var5.set(self.p_cur[1][1])
#variables as scale widgets
scale1 = Scale(root,from_=100,to=0,orient=VERTICAL,sliderlength=10,variable=s_var1)
scale2 = Scale(root,from_=100,to=0,orient=VERTICAL,sliderlength=10,variable=s_var2)
scale3 = Scale(root,from_=100,to=0,orient=VERTICAL,sliderlength=10,variable=s_var3)
scale4 = Scale(root,from_=100,to=0,orient=VERTICAL,sliderlength=10,variable=s_var4)
scale5 = Scale(root,from_=100,to=0,orient=VERTICAL,sliderlength=10,variable=s_var5)
#displaying the scale widgets on the screen
scale1.grid(row=0,column=0)
scale2.grid(row=0,column=1)
scale3.grid(row=0,column=2)
scale4.grid(row=0,column=3)
scale5.grid(row=0,column=4)
#disabling the scales
scale1.config(state=DISABLED)
scale2.config(state=DISABLED)
scale3.config(state=DISABLED)
scale4.config(state=DISABLED)
scale5.config(state=DISABLED)
v_file.close()
#displaying the buttons on the screen
Button(root,text=qn1,command=lambda: Game.qn_func(self,n_qn1)).place(relx=0.2,rely=0.7,anchor=W,width=200,height=50)
Button(root,text=qn2,command=lambda: Game.qn_func(self,n_qn2)).place(relx=0.8,rely=0.7,anchor=E,width=200,height=50)
game = Game()
game.start()
root.mainloop()

You can see in this particular section that you have called on 'qn' before it was even defined:
#function to display question and variables
def qn_func(self,qn_num) :
Game.clear(self)
#accessing the questions
q_file = StringIO(qn)
#reading the question, options, next qn numbers and the character name from the file
qn_list = q_file.readlines()
qn = qn_list[qn_num-1].strip().split("$")[1]
The variable needs to be assigned a value before being used. Here, you call q_file = StringIO(qn) before you have defined qn = qn_list....

Related

Differences in tkinter Window between normal and debugging mode

Code:
fields = ['Label1','Label2','Label3','Label4','Label5','Label6']
selected_item = ['Entry1','Entry2','Entry3','Entry4','Entry5','Label6']
stringvar_list = [tk.StringVar() for s in range(len(selected_item))]
for var in range(len(stringvar_list)):
stringvar_list[var].set(selected_item[var])
for i in range(len(fields)):
lbl = ttk.Label(root,text=fields[i])
ent = ttk.Entry(root,textvariable=stringvar_list[i])
lbl.grid(row=row,column=col,padx=2,pady=2)
ent.grid(row=row,column=col+1,padx=2,pady=2)
row+=1
When I run this code, I get this(the entries are not filled):
But when I run the same code in debugging mode,no changes - I just skip through the breakpoint, I get this(Entries are filled):
I'm using VS Code, if it matters.
Extended Code:
def modify(fields):
# fields = fields[1:] #Original
fields = ['Label1','Label2','Label3','Label4','Label5','Label6'] # For Simplicity and Underestanding
# selected_item = tree.item(tree.selection()[0])['values'][1:] #Original
selected_item = ['Entry1','Entry2','Entry3','Entry4','Entry5','Label6'] # For Simplicity and Underestanding
modify_top = tk.Toplevel(root)
stringvar_list = [tk.StringVar() for s in range(len(selected_item))]
for var in range(len(stringvar_list)):
stringvar_list[var].set(selected_item[var])
row = 0
col = 0
frm = ttk.Frame(modify_top)
for i in range(len(fields)):
lbl = ttk.Label(frm,text=fields[i])
ent = ttk.Entry(frm,textvariable=stringvar_list[i])
lbl.grid(row=row,column=col,padx=2,pady=2)
ent.grid(row=row,column=col+1,padx=2,pady=2)
row+=1
frm.grid(sticky='nsew',row=0,column=0,padx=30,pady=20)
make_changes_btn = ttk.Button(modify_top,text='Make Changes',command = lambda : make_changes())
make_changes_btn.grid(row=1,column=0)
Issues:
As #acw1668 commented, making stringvar_list global did the job, but I'm referencing it's values in the same function, so that shouldn't be a problem.
Even if the issue is with the scope, then why does the program work fine in debugging mode?

Python tkinter label not appearing when using textvariable

I am a high school student trying to create a quiz program that selects random true or false questions.
What I want to do is get the label AnswerQuestionPageText2 (with the text variable AnswerQuestionPageText2Variable) reload when the button AnswerQuestionPageButton4 is pressed. Before it is pressed, it should read Please click 'reload question'. However, AnswerQuestionPageText2 doesn't show at all.
Thanks for any help. But please, don't send hate to me. I have already tried asking on stack overflow and that was all I got.
Code:
from tkinter import *
from tkinter.font import *
from tkinter import messagebox
import random
#variables
IQ = 0
int(IQ)
#lists
TrueQuestions = [
'true question 1',
'true question 2',
'true question 3',]
current_question = random.choice(TrueQuestions)
#command defines
def MainMenuButton1Command():
MainMenu.withdraw()
AnswerQuestionPage.deiconify()
def MainMenuButton2Command():
pass
def MainMenuButton3Command():
pass
def MainMenuButton4Command():
pass
def MainMenuButton5Command():
quit()
def AnswerQuestionPageButton1Command():
AnswerQuestionPage.withdraw()
MainMenu.deiconify()
def AnswerQuestionPageButton2Command():
pass
def AnswerQuestionPageButton3Command():
pass
def AnswerQuestionPageButton4Command():
current_question = random.choice(TrueQuestions)
AnswerQuestionPageText2variable.set("Question: "+str(current_question))
AnswerQuestionPageText2variable.get()
#MainMenu
MainMenu = Tk()
MainMenu.attributes("-fullscreen", True)
MainMenu.title("IQ extreme Main Menu")
MainMenu.configure(bg="blue")
BigFont = Font(family="Tahoma",size=48,weight="bold")
SmallFont = Font(family="Tahoma",size=24)
TinyFont = Font(family="Tahoma",size=18)
MainMenuText1 = Label(MainMenu,bg="blue",fg="black",font=TinyFont,text="MAIN MENU")
MainMenuText1.place(x=1130,y=0)
MainMenuText2 = Label(MainMenu,bg="blue",fg="black",font=SmallFont,text="IQ")
MainMenuText2.place(x=400,y=75)
MainMenuText3 = Label(MainMenu,bg="blue",fg="black",font=BigFont,text="EXTREME")
MainMenuText3.place(x=500,y=120)
MainMenuText4 = Label(MainMenu,bg="blue",fg="black",font=TinyFont,text="Current IQ: "+str(IQ))
MainMenuText4.place(x=575,y=275)
MainMenuButton1 = Button(MainMenu,bg="white",fg="black",font=TinyFont,text="Start",width=20,command=MainMenuButton1Command)
MainMenuButton1.place(x=525,y=400)
MainMenuButton2 = Button(MainMenu,bg="white",fg="black",font=TinyFont,text="Upgrade",width=20,command=MainMenuButton2Command)
MainMenuButton2.place(x=525,y=475)
MainMenuButton3 = Button(MainMenu,bg="white",fg="black",font=TinyFont,text="See Data",width=20,command=MainMenuButton3Command)
MainMenuButton3.place(x=525,y=550)
MainMenuButton4 = Button(MainMenu,bg="white",fg="black",font=TinyFont,text="How to play",width=20,command=MainMenuButton4Command)
MainMenuButton4.place(x=25,y=950)
MainMenuButton5 = Button(MainMenu,bg="red",fg="black",font=TinyFont,text="Quit",width=5,command=MainMenuButton5Command)
MainMenuButton5.place(x=0,y=0)
#AnswerQuestionPage
AnswerQuestionPage = Tk()
AnswerQuestionPage.withdraw()
BigFont = Font(AnswerQuestionPage,family="Tahoma",size=48,weight="bold")
SmallFont = Font(AnswerQuestionPage,family="Tahoma",size=24)
TinyFont = Font(AnswerQuestionPage,family="Tahoma",size=18)
AnswerQuestionPage.attributes("-fullscreen", True)
AnswerQuestionPage.title("IQ extreme")
AnswerQuestionPage.configure(bg="blue")
AnswerQuestionPageText1 = Label(AnswerQuestionPage,bg="blue",fg="black",font=SmallFont,text="Current IQ: "+str(IQ))
AnswerQuestionPageText1.place(x=0,y=0)
AnswerQuestionPageText2variable = StringVar()
AnswerQuestionPageText2variable.set("Please click 'reload question'")
AnswerQuestionPageText2 = Label(AnswerQuestionPage,bg="blue",fg="black",font=BigFont,textvariable=AnswerQuestionPageText2variable)
AnswerQuestionPageText2.place(x=350,y=75)
AnswerQuestionPageButton1 = Button(AnswerQuestionPage,bg="white",fg="black",font=TinyFont,text="Home",width=5,command=AnswerQuestionPageButton1Command)
AnswerQuestionPageButton1.place(x=1205,y=5)
AnswerQuestionPageButton2 = Button(AnswerQuestionPage,bg="green",fg="black",font=BigFont,text="True",width=10,command=AnswerQuestionPageButton2Command)
AnswerQuestionPageButton2.place(x=120,y=500)
AnswerQuestionPageButton3 = Button(AnswerQuestionPage,bg="red",fg="black",font=BigFont,text="False",width=10,command=AnswerQuestionPageButton3Command)
AnswerQuestionPageButton3.place(x=760,y=500)
AnswerQuestionPageButton4 = Button(AnswerQuestionPage,bg="white",fg="black",font=TinyFont,text="Reload question",width=20,command=AnswerQuestionPageButton4Command)
AnswerQuestionPageButton4.place(x=500,y=0)

can't get Variable value of groups of ttk.CheckButtons

I'm creating 3 groups of ttk.CheckButtons, using a class clsGrpCheckButton.
The problem is that I can access only the status of the last group created, and not for the previous group.
When clicking on one of the checkButtons of any group, I'm expecting to get the list of checkbuttons check in the group (by using method chkGrpGetValue with is the command parameter of each checkbutton)
However, whatever which button is clicked, the method only and always returns the status of the last group
Here is the code to recreate the issue, and in attachment a picture that shows the problems
Thks for your help.
Rgds
import tkinter as tk
from tkinter import ttk
import pandas as pd
class clsGrpCheckButton(ttk.Checkbutton):
def __init__(self,pContainer, pLstVal,pCommand,pInitValue=True):
self.grpChk=[0]*len(pLstVal)
self.grpKey=[0]*len(pLstVal)
self.grpLstVal = [0]*len(pLstVal)
self.grpVariable= [0]*len(pLstVal)
self.grpActiveKeys = [0]
for l,t in enumerate(pLstVal):
#l : index of the list of tuples
self.grpKey[l] = t[0]
self.grpLstVal[l] = t[1]
self.grpVariable[l] = tk.StringVar()
self.grpChk[l] = ttk.Checkbutton(pContainer, text=self.grpLstVal[l],
state='active' ,
onvalue= self.grpKey[l],
offvalue= '',
variable = self.grpVariable[l],
command=pCommand)
#get default value
if pInitValue :
self.grpVariable[l].set(self.grpKey[l])
self.grpActiveKeys.append(self.grpKey[l])
#get the index in the list of checkboxes
# depending on the key
def chkGrpGetIdx(self, pKey):
i=0
while i <len(self.grpKey):
if self.grpKey[i]==pKey :
return i
i=len(self.grpKey)
else:
i+=1
def chkGrpSetValue(self, pKey, pValue):
#need find correct index first
i=self.chkGrpGetIdx(pKey)
self.grpVariable[i] = pValue
#return the list of keys of the group
def chkGrpKeyLst(self):
return self.grpKey
#return the checkox element of the group of checkox
def chkGrpGetChkObj(self,pKey):
i=self.chkGrpGetIdx(pKey)
return self.grpChk[i]
#action when check/uncheck
#at list one element should be active
def chkGrpGetValue(self):
i=0
r=len(self.grpVariable)
self.grpActiveKeys.clear()
while i < len(self.grpVariable):
if self.grpVariable[i].get() =='':
r-=1
else:
self.grpActiveKeys.append(self.grpKey[i])
i+=1
if r==0:
self.grpVariable[0].set(self.grpKey[0])
self.grpActiveKeys.append(self.grpKey[0])
print(self.grpActiveKeys)
#to avoid accessing to class attribute directly
def chkGetCheckedValues(self):
return self.grpActiveKeys
class clsWindows(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
la = [1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3]
lb= [10,11,12,14,15,20,21,22,23,24,25,26,30,31,32,33]
lc=['d10','d11','d12','d14','d15','d20','d21','d22','d23','d24','d25','d26','d30','d31','d32','d33']
df = pd.DataFrame(
{'DIVISION': la,
'DEPT_CODE': lb,
'DEPT_NAME': lc
})
lW = list(zip(df['DIVISION'].astype(str) , df['DEPT_CODE'].astype(str)))
lpt = list(zip(df['DEPT_CODE'].astype(str) , df['DEPT_NAME'].astype(str)))
curHead = ""
r=0
c=-1
for head, DPT in lW:
if not curHead==head:
curHead = head
c+=1
r=0
dq=df.query('DIVISION=='+head)
lpt = list(zip(dq['DEPT_CODE'].astype(str) , dq['DEPT_NAME'].astype(str)))
t=ttk.Labelframe(self,text=head)
t.grid(column=c, row=0, sticky='nw')
self.checkGrpDept= clsGrpCheckButton(t,lpt,lambda:self.checkGrpDept.chkGrpGetValue(),True)
self.checkGrpDept.chkGrpGetChkObj(DPT).grid(column=c, row=r, sticky='nw')
t.rowconfigure(r, weight=1)
t.columnconfigure(c, weight=1)
r+=1
def wQuit(self):
self.destroy()
app = clsWindows()
app.mainloop()
Example of issue
finally, I came up with a solution by using partial when assigning the command to each checkbutton.
Here is the full code if someone faces a similar issue
import tkinter as tk
from tkinter import ttk
import pandas as pd
from functools import partial
class clsGrpCheckButton():
def __init__(self,pContainer, pLstVal,pCommand,pInitValue=True):
self.grpChk=[0]*len(pLstVal)
self.grpKey=[0]*len(pLstVal)
self.grpLstVal = [0]*len(pLstVal)
self.grpVariable= [0]*len(pLstVal)
self.grpActiveKeys = [0]
for l,t in enumerate(pLstVal):
#l : index of the list of tuples
self.grpKey[l] = t[0]
self.grpLstVal[l] = t[1]
self.grpVariable[l] = tk.StringVar()
self.grpChk[l] = ttk.Checkbutton(pContainer, text=self.grpLstVal[l],
state='active' ,
onvalue= self.grpKey[l],
offvalue= '',
variable = self.grpVariable[l],
command=partial(pCommand,self))
#get default value
if pInitValue :
self.grpVariable[l].set(self.grpKey[l])
self.grpActiveKeys.append(self.grpKey[l])
#get the index in the list of checkboxes
# depending on the key
def chkGrpGetIdx(self, pKey):
i=0
while i <len(self.grpKey):
if self.grpKey[i]==pKey :
return i
i=len(self.grpKey)
else:
i+=1
def chkGrpSetValue(self, pKey, pValue):
#need find correct index first
i=self.chkGrpGetIdx(pKey)
self.grpVariable[i] = pValue
#return the list of keys of the group
def chkGrpKeyLst(self):
return self.grpKey
#return the checkox element of the group of checkox
def chkGrpGetChkObj(self,pKey):
i=self.chkGrpGetIdx(pKey)
return self.grpChk[i]
#action when check/uncheck
#at list one element should be active
def chkGrpGetValue(self):
i=0
r=len(self.grpVariable)
self.grpActiveKeys.clear()
while i < len(self.grpVariable):
if self.grpVariable[i].get() =='':
r-=1
else:
self.grpActiveKeys.append(self.grpKey[i])
i+=1
if r==0:
self.grpVariable[0].set(self.grpKey[0])
self.grpActiveKeys.append(self.grpKey[0])
print(self.grpActiveKeys)
#to avoid accessing to class attribute directly
def chkGetCheckedValues(self):
return self.grpActiveKeys
class clsWindows(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
la = [1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3]
lb= [10,11,12,14,15,20,21,22,23,24,25,26,30,31,32,33]
lc=['d10','d11','d12','d14','d15','d20','d21','d22','d23','d24','d25','d26','d30','d31','d32','d33']
df = pd.DataFrame(
{'DIVISION': la,
'DEPT_CODE': lb,
'DEPT_NAME': lc
})
lW = list(zip(df['DIVISION'].astype(str) , df['DEPT_CODE'].astype(str)))
lpt = list(zip(df['DEPT_CODE'].astype(str) , df['DEPT_NAME'].astype(str)))
curHead = ""
r=0
c=-1
for head, DPT in lW:
if not curHead==head:
curHead = head
c+=1
r=0
dq=df.query('DIVISION=='+head)
lpt = list(zip(dq['DEPT_CODE'].astype(str) , dq['DEPT_NAME'].astype(str)))
t=ttk.Labelframe(self,text=head)
t.grid(column=c, row=0, sticky='nw')
checkGrpDept= clsGrpCheckButton(t,lpt,clsGrpCheckButton.chkGrpGetValue,True)
checkGrpDept.chkGrpGetChkObj(DPT).grid(column=c, row=r, sticky='nw')
t.rowconfigure(r, weight=1)
t.columnconfigure(c, weight=1)
r+=1
def wQuit(self):
self.destroy()
app = clsWindows()
app.mainloop()

How do I determine what checkbuttons selected when created dynamically?

I am creating a custom file chooser in tkinter. I am creating a grid of checkbuttons representing files in a directory. Right now all i want to do is get a list of the file names a user chooses. As of now my code displays the gui nicely but when I try to determine what boxes the user checked it's not working. I'm not sure what I'm doing wrong. Most likely in the way i'm setting the variable for the checkbutton. I know this would be easy for a python pro but i'm not a pro so any help would be greatly appreciated. See my code below. Apologies ahead of time for the huge amount of code but i'm not sure where i'm going wrong so i put it all in.
Mark
class scareGUI:
def __init__(self, master):
self.selectedFileName = StringVar()
#filter non video file types
includes = ['*.mp4','*.py']
includes = r'|'.join([fnmatch.translate(x) for x in includes])
#master.attributes('-zoomed', True)
self.frame_header = ttk.Frame(master)
self.frame_header.pack()
ttk.Label(self.frame_header, text="TerrorForm ScareBox").grid(row=0, column = 0, rowspan = 2)
self.frame_files = ttk.Frame(master)
self.frame_files.pack()
self.frame_footer = ttk.Frame(master)
self.frame_footer.pack()
#pull file names from file system
for root, dirs, self.files in os.walk('./movies'):
self.files = [os.path.join(root, f) for f in self.files]
self.files = [f for f in self.files if re.match(includes, f)]
#Determine number of rows in grid
numfiles = len(self.files)
dividesBy = False
numRows = IntVar()
numColumns = 4
while (dividesBy == False):
if(numfiles % numColumns == 0):
numRows=int(numfiles/numColumns)
dividesBy = True
else:
numfiles+=1
#Print Check Boxes in Grid layout
filmIcon = PhotoImage(file='tf_film_icon.gif')
i=0
self.checkedFiles=[None]*len(self.files)
for r in range(numRows):
for c in range(4):
if (i<len(self.files)):
self.checkedFiles[i] = IntVar()
checkbutton = ttk.Checkbutton(self.frame_files, text=self.files[i], variable=self.checkedFiles[i])
checkbutton.config(image = filmIcon,compound = TOP)
checkbutton.image = filmIcon
checkbutton.grid(row = r, column = c)
i += 1
def getChosenFiles(self):
self.chosenFiles=[]
for x in range(len(self.files)):
if(self.checkedFiles[x].get()):
self.chosenFiles.append(self.files[x])
print (self.chosenFiles[0])
return self.chosenFiles
def main():
root = Tk()
scaregui = scareGUI(root)
root.mainloop()
if __name__ == "__main__": main()

Python sqlite3, tkinter display multible rows

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:

Categories

Resources