Using validation on text entry box - python

I am trying to set up validation on text entry boxes. Three of the boxes need to only accept integers and one text as a postcode. I am not sure whether to do this in a function previously defined or when the entry boxes are created. Also how would i make the values from the text entry boxes be accessable in the function QuoteCreation. All my code is below.
from tkinter import *
class quote():
def __init__(self, master):
self.master=master
self.master.title("Quote Screen")
self.master.geometry("2100x1400")
self.master.configure(background = "white")
self.Borras = PhotoImage(file = "Borras.Logo.2.gif") #sets up image
self.Borras.image = self.Borras
self.BorrasLabel = Label(self.master, image = self.Borras, bg = "white")#puts image onto label
self.BorrasLabel.place(anchor=NW)
self.Title = Label(self.master, text = "New Quote", font = ("calibri", 20), bg = "White")
self.Title.place(x=650, y = 10)
self.SubmitButton = PhotoImage(file = "Submit.Button.gif") #sets up image
self.SubmitButton.image = self.SubmitButton
self.SubmitButtonLabel = Button(self.master, image = self.SubmitButton, bg = "white", command= self.QuoteCreation)#puts image onto a button
self.SubmitButtonLabel.place(x=900, y=290)
PostCodeVar = StringVar()
PostCodeEntry = Entry(master,width=50, font=20, textvariable=PostCodeVar)
PostCodeEntry.place(x = 20, y = 150)
PostCodeVar.set("Please enter the Post Code")
PostCodeValue = PostCodeVar.get()
HeightVar = StringVar()
HeightEntry = Entry(master, width=50, font=20, textvariable=HeightVar)
HeightEntry.place(x = 20, y = 220)
HeightVar.set("Please enter the Height")
HeightValue = HeightVar.get()
LengthVar = StringVar()
LengthEntry = Entry(master, width=50, font=20, textvariable=LengthVar)
LengthEntry.place(x = 20, y = 290)
LengthVar.set("Please enter the Length")
LengthValue = LengthVar.get()
PitchVar = StringVar()
PitchEntry = Entry(master, width=50, font=20, textvariable=PitchVar)
PitchEntry.place(x = 20, y = 360)
PitchVar.set("Please enter the Pitch")
PitchValue = PitchVar.get()
RiseVar = StringVar()
RiseEntry = Entry(master, width=50, font=20, textvariable=RiseVar)
RiseEntry.place(x = 20, y = 430)
RiseVar.set("Please enter the Rise")
RiseValue = RiseVar.get()
self.SubmitButton = PhotoImage(file = "Submit.Button.gif")
self.SubmitButton.image = self.SubmitButton
self.SubmitButtonLabel = Button(self.master, image = self.SubmitButton, bg = "white", command= self.QuoteCreation)#puts image onto a button
self.SubmitButtonLabel.place(x=900, y=290)
def on_button(self):
print(self.entry.get())
def QuoteCreation(self):
print(' ')
def quitWindow(self):
self.master.destroy()
def backToWelcome(self):
self.master.destroy()

You would set up separate functions to deal with the validation, when the submit button is pressed.
So, as an example, your submit button may look a bit like this:
submitButton = Button(master, text="Submit", command=validation)
The validation, in your case would then want to carry out these checks:
def validation():
postcode = PostCodeVar.get()
length = LengthVar.get()
pitch = PitchVar.get()
rise = RiseVar.get()
if postcodeCheck(postcode) == True and length.isdigit() == True and pitch.isdigit() == True and rise.isdigit() == True:
#carry out chosen process
In your case, you can try setting the postcode, length, pitch and height variables before calling the function, and setting them as global. The postcode should be created, and if it is okay, the function should then:
return True
...so it matches the outcome of the if statement.
I hope this is what you were looking for, and can adapt the example to your specific problem!

Related

Activate Entry Box from Listbox in Tkinter

I'm trying to create a GUI to collect three inputs from a user, where the first input has two options (based on a Listbox), like the image below (where the option "NACA" is selected):
The problem is with the Listbox. I guess the options are overlapping each other. For example, If I select the NACA option (image above), and then I select the .txt option, some part of the NACA label remains:
And of course, just the labels are appearing, not the entry_boxes to type inside (if I delete the part of the listBox, the entry_boxes of the last two input appers, so I really guess the problem is with the ListBox)
import tkinter as tk
root = tk.Tk()
root.geometry('400x300')
root.resizable(0, 0)
menu_inicial = tk.Canvas(root, width = 400, height = 300)
menu_inicial.pack()
def naca_box():
naca_entry_box = tk.Entry(menu_inicial)
menu_inicial.create_window(200, 30, window=naca_entry_box)
naca_label = tk.Label(root, text="Enter NACA:")
naca_label.pack()
naca_label.place(x=50, y = 50)
def txt_box():
txt_entry_box = tk.Entry(menu_inicial)
menu_inicial.create_window(200, 30, window=txt_entry_box)
txt_label = tk.Label(root, text="Enter .txt:")
txt_label.pack()
txt_label.place(x=50, y = 50)
def aoa_box():
aoa_entry_box = tk.Entry(root)
menu_inicial.create_window(200, 60, window=aoa_entry_box)
aoa_label = tk.Label(root, text="Enter AoA (º):")
aoa_label.pack()
aoa_label.place(x=50, y = 80)
def panel_box():
panel_entry_box = tk.Entry(root)
menu_inicial.create_window(200, 90, window=panel_entry_box)
panel_label = tk.Label(root, text="Enter Nº Panels:")
panel_label.pack()
panel_label.place(x=40, y = 110)
def update_box(*args):
selection = box_list.curselection()
lb_value.set(options[selection[0]] )
if selection[0] == 0:
naca_box()
else:
txt_box()
options = ['NACA', '.txt']
listCon = tk.StringVar(value=options)
box_list = tk.Listbox(menu_inicial, listvariable=listCon, width=10, height=2, selectmode=tk.SINGLE)
box_list.grid(row=0, column=0)
box_list.bind('<<ListboxSelect>>', update_box)
lb_value=tk.StringVar()
aoa_box()
panel_box()
root.mainloop()
How can I proceed with this? Is a problem with the "IF" statement to choose the options ? (I don't know if this is the best what to do this...)
The problem is that while you clicking button each time,
you are creating label each time,
if you want to change the text in the label you created,use 'config()'
change your code like this,
sample_label=tk.Label(root)
sample_label.place(x=50, y = 50)
def naca_box():
naca_entry_box = tk.Entry(menu_inicial)
menu_inicial.create_window(200, 30, window=naca_entry_box)
sample_label.config(text="Enter NACA:")
def txt_box():
txt_entry_box = tk.Entry(menu_inicial)
menu_inicial.create_window(200, 30, window=txt_entry_box)
sample_label.config(text="Enter .txt:")

tkinter throws error using a variable for button name to set state

I want to pass a button name to tkinter as a variable. This method works for Text fields, but not for buttons in my code.
I am building a gui app and I want to have a generic clear function that zaps a text entry field and resets a button from NORMAL to DiSABLED.
There are multiple buttons and fields, hence the desire to make this generic.
For the code I have, the buttons are present with the exception of clear all.
I am setting the variable w_button to the specific name of the (existing) button based on what is passed to the function.
def switch_clear(elem_type):
if elem_type == 'scn':
w_button = 'b_clear_scn'
clear_field = 'scn_file_entry'
print ('scenario')
elif elem_type == 'sol2':
w_button = 'b_clear_sol2'
clear_field = 'sol2_file_entry'
print ('sol2')
elif elem_type == 'mdl':
w_button = 'b_clear_mdlList'
clear_field = 'mdlList_file_entry'
print ('mdl')
elif elem_type == 'all':
print ('clear all TBD')
return()
if w_button["state"] == NORMAL:
clear_field.delete(0, END)
w_button["state"] = DISABLED
return()
Here's what happens:
C:\utils>my_frame3.py
scenario
Traceback (most recent call last):
File "C:\utils\my_frame3.py", line 127, in <module>
b_clear_scn = Button(first_frame, text = "Clear scenario", command = switch_clear('scn'), height = 2, state=DISABLED)
File "C:\utils\my_frame3.py", line 100, in switch_clear
if w_button["state"] == NORMAL:
TypeError: string indices must be integers
C:\utils>
I realize I could duplicate and push the clear operations into the if/elif statements, and I may have to live with that but - is it possible to reference buttons as variables? How can I do this?
Complete code as requested below. The preview is a mess despite using the code widget, but in my file lines are correctly formatted (notepad++). Tx
import os, sys
from tkinter import *
from tkinter import messagebox
from tkinter import filedialog
root2 = Tk()
root2.title('Model Processing')
root2.geometry('{}x{}'.format(512, 400))
# colors
color1 = 'light cyan'
color2 = 'gold'
color3 = 'RosyBrown1'
color4 = 'lavender'
color5 = 'linen'
bg_color = 'azure'
# number of items to process; until >1 OK is disabled; if >1 OK is enabled TBD
l_to_do = [] # items to process; scn, sol2, modelList, installed models
# functions/commands
def callback():
print ('A button was clicked.')
return;
def my_exit():
result = messagebox.askquestion("Cancel Model Processing", "Are you sure?", icon='warning')
if result == 'yes':
root2.quit()
else: # user changed mind
pass
def choose_import_file(str_ftype):
which_field = ''
which_clear_btn = ''
ftype = str_ftype
mdl_opts = {}
if ftype == 'scn':
title_msg = 'Choose a scenario file'
mdl_opts['filetypes'] = [('Supported types', ('.scn')),
('scenario files',('.scn'))]
which_field = scn_file_entry
which_clear_btn = 'b_clear_scn'
elif ftype == 'sol2':
title_msg = 'Choose a SOL2 file'
mdl_opts['filetypes'] = [('Supported types', ('.txt')),
('sol2 files',('.txt'))]
which_field = sol2_file_entry
elif ftype == 'mdllist':
title_msg = 'Choose a ModelList file'
print ('TBD: ModelList file')
file_input = filedialog.askopenfilename(title = title_msg, **mdl_opts)
if file_input == '':
print ('error or cancelled by user')
return
else:
f_inp_file = os.path.basename(file_input)
f_inp_file_base = str(file_input.split('.')[0])
f_inp_file_ext = str.lower(str(file_input.split('.')[1]))
f_inp_d_name = os.path.dirname(file_input)
print('File chosen:', f_inp_file_base)
# populate scenario file field
which_field.insert(INSERT,file_input)
which_clear_btn["state"] = NORMAL
# define appropriate clear button active
# define_clear_btn.configure(state = ACTIVE)
return
def switch_clear(elem_type):
if elem_type == 'scn':
if b_clear_scn["state"] == NORMAL:
scn_file_entry.delete(0, END)
b_clear_scn["state"] = DISABLED
elif elem_type == 'sol2':
f b_clear_sol2["state"] == NORMAL:
clear_field = 'sol2_file_entry'
b_clear_sol2["state"] = DISABLED
elif elem_type == 'mdl':
if b_clear_mdlList["state"] == NORMAL:
clear_field = 'mdlList_file_entry'
b_clear_mdlList["state"] = DISABLED
elif elem_type == 'all':
print ('clear all TBD')
return()
return()
# create all of the main containers
first_frame = Frame(root2, bg=color5, width = 512, height=90, pady=10)
second_frame = Frame(root2, bg=color5, width = 512, height=90, pady=10)
third_frame = Frame(root2, bg=color5, width=512, height=90, pady=10)
fourth_frame = Frame(root2, bg=color5, width = 512, height = 90, pady=10)
# layout all of the main containers
root2.grid_rowconfigure(3, weight=1)
root2.grid_rowconfigure(2, weight=1)
root2.grid_rowconfigure(1, weight=1)
root2.grid_columnconfigure(0, weight=1)
first_frame.grid(row=0, sticky="ew")
second_frame.grid(row=1, sticky="ew")
third_frame.grid(row=2, sticky="ew")
fourth_frame.grid(row = 3, sticky="e")
# create the widgets for the first frame
#scn_label = Label(first_frame, text = 'Scenario file')
scn_file_entry = Entry(first_frame, background=bg_color, width = 50)
b_choose_scn = Button(first_frame, text = "Choose a scenario..", command = lambda: choose_import_file('scn'), height = 2)
b_clear_scn = Button(first_frame, text = "Clear scenario", command = switch_clear('scn'), height = 2, state=DISABLED)
# layout the widgets in the first frame
#scn_label.grid(row = 0, column = 0, padx = (10,50), pady=5)
scn_file_entry.grid(row = 0, column = 1, padx = (10,10))
b_choose_scn.grid(row=0, column=0, padx = (10,10), sticky=W)
b_clear_scn.grid(row=2, column=0, padx = (10,10), sticky=W)
# second frame
# sol2_label = Label(second_frame, text = 'Sol2 file')
sol2_file_entry = Entry(second_frame, background=bg_color, width = 50)
b_choose_sol2 = Button(second_frame, text = "Choose SOL2 file..", command = lambda: choose_import_file('sol2'), height = 2)
b_clear_sol2 = Button(second_frame, text = "Clear SOL2", command = switch_clear('sol2'), height = 2, state=DISABLED)
# layout the widgets in the second frame
# sol2_label.grid(row = 0, column = 0, padx = (10,50), pady=5)
sol2_file_entry.grid(row = 0, column = 1, padx = (10,10), sticky=EW)
b_choose_sol2.grid(row=0, column=0, padx = (10,10), sticky=W)
b_clear_sol2.grid(row=2, column=0, padx = (10,10), sticky=W)
# third frame
# mdlList_label = Label(third_frame, text = 'ModelList.txt file')
mdlList_file_entry = Entry(third_frame, background=bg_color, width = 50)
b_choose_mdlList = Button(third_frame, text = "Choose ModelList.txt file..", command = callback, height = 2)
b_clear_mdlList = Button(third_frame, text = "Clear ModelList", command = callback, height = 2, state=DISABLED)
# layout the widgets in the third frame
#mdlList_label.grid(row = 0, column = 0, padx = (10,10), pady=5, sticky = 'ns')
mdlList_file_entry.grid(row = 0, column = 1, padx = (10,10), sticky=EW)
b_choose_mdlList.grid(row=0, column=0, padx = (10,10), sticky=W)
b_clear_mdlList.grid(row=2, column=0, padx = (10,10), sticky=W)
#####################################################################
# create bottom widgets
#####################################################################
clear_all = Button(fourth_frame, text='Clear All', padx = '5', command = callback, height = 2, state=DISABLED)
ok_btn = Button(fourth_frame, text='OK', padx = '5', command = callback, height = 2, state=DISABLED)
cancel_btn = Button(fourth_frame, text='Cancel', height = 2, padx = '12', command = my_exit)
#####################################################################
# layout the bottom widgets
#####################################################################
clear_all.grid(row = 0, column = 2, sticky = 'e')
ok_btn.grid(row = 0, column = 3, sticky = 'e')
cancel_btn.grid(row = 0, column = 4, sticky = 'e')
# commands/bindings
root2.mainloop()
I believe this is what you are trying to do. The below is fully commented with explanations. switch_clear becomes entirely unnecessary with this method. The buttons directly clear their corresponding entry in their command, and Entry validation takes care of the corresponding button state.
Note: I wrote all of this before you posted your full code
import tkinter as tk
root = tk.Tk()
root.geometry('400x400')
#toggle the state of buttons based on entry text length
def toggle_button(name, text):
global btn_switch
btn_switch[name]['state'] = 'normal' if len(text) else 'disabled'
return True
#to hold the buttons so they are easy to position
#just for this example
buttons = tk.Frame(root)
buttons.pack(side='top', anchor='nw')
#create a tcl wrapper for the validate command
vcmd = tk.Widget.register(root, toggle_button)
#mock-up of your entries ~ validate on key press. send widget name and full text to vcmd
scn_file_entry = tk.Entry(root, width=20)
scn_file_entry.configure(validate="key", validatecommand=(vcmd, '%W', '%P'))
scn_file_entry.pack(side='left', anchor='nw')
sol2_file_entry = tk.Entry(root, width=20)
sol2_file_entry.configure(validate="key", validatecommand=(vcmd, '%W', '%P'))
sol2_file_entry.pack(side='left', anchor='nw')
mdlList_file_entry = tk.Entry(root, width=20)
mdlList_file_entry.configure(validate="key", validatecommand=(vcmd, '%W', '%P'))
mdlList_file_entry.pack(side='left', anchor='nw')
#mock-up of your buttons ~ delete the entry text in a lambda and let entry validation handle the button state
b_clear_scn = tk.Button(buttons, text="scn", state='disabled')
b_clear_scn.configure(command=lambda: scn_file_entry.delete(0, 'end'))
b_clear_scn.pack(side='left', anchor='nw')
b_clear_sol2 = tk.Button(buttons, text="sol2", state='disabled')
b_clear_sol2.configure(command=lambda: sol2_file_entry.delete(0, 'end'))
b_clear_sol2.pack(side='left', anchor='nw')
b_clear_mdlList = tk.Button(buttons, text="mdl", state='disabled')
b_clear_mdlList.configure(command=lambda: mdlList_file_entry.delete(0, 'end'))
b_clear_mdlList.pack(side='left', anchor='nw')
#create a dictionary of 'widget name':corresponding button, for toggle_button to reference
btn_switch = {
f'{scn_file_entry}':b_clear_scn,
f'{sol2_file_entry}':b_clear_sol2,
f'{mdlList_file_entry}':b_clear_mdlList,
}
root.mainloop()

tkinter, Image does not show up unless some function added

I have written a code for a basic game but the image and shape don't show up unless I add something like item.pack() or win.mainloop() [which doesn't really make sense] but then the lines below it don't run.
When I don't have anything, the buttons show up but the image doesn't show up.
import tkinter as tk
import random
from tkinter import messagebox
win = tk.Tk()
my_label = tk.Label(win, text="Color of the Baloon Game")
my_label.pack()
my_canvas = tk.Canvas(win, width=400, height=600)
my_canvas.pack()
background_image=tk.PhotoImage(file = "CS_Game_menu.png")
background_label = tk.Label(my_canvas, image=background_image)
background_label.photo = background_image
background_label.grid(row = 0, rowspan = 10, column = 0, columnspan = 10)
def drawCircle():
color = "green"
x1 = 265
y1 = 80
diameter = 90
my_canvas.destroy()
circle_button.destroy()
quit_button.destroy()
my_label.destroy()
my_label1 = tk.Label(win, text="What is the Color of the Baloon?", font="Purisa")
my_label1.pack()
my_canvas1 = tk.Canvas(win, width=400, height=600)
my_canvas1.pack()
image1 = r"CS_Game_baloon.png"
photo1 = tk.PhotoImage(file=image1)
item = my_canvas1.create_image(200, 350, image=photo1)
shape = my_canvas1.create_oval(x1, y1, x1 + diameter, y1 + diameter+20, fill=color)
item.pack()
game1_button = tk.Button(my_canvas1, text = "Green")
game1_button.grid(row= 8, column = 3)
game1_button["command"] = lambda: messagebox.showinfo("Congratulations!", "Correct Answer!")
game2_button = tk.Button(my_canvas1, text = "Blue")
game2_button.grid(row= 8, column = 5)
game2_button["command"] = lambda: messagebox.showinfo("Sorry!", "Incorrect Answer!")
game3_button = tk.Button(my_canvas1, text = "Red")
game3_button.grid(row= 8, column = 7)
game3_button["command"] = lambda: messagebox.showinfo("Sorry", "Incorrect Answer!")
circle_button = tk.Button(win, text="New Game")
circle_button.pack()
circle_button["command"] = drawCircle
quit_button = tk.Button(win, text="Quit")
quit_button.pack()
quit_button['command'] = win.destroy
You are using both the create_... methods and grid methods on your canvas object. It won't behave as you expected.
To achieve what you want, you can create a Frame, put your buttons in it, and then use create_window method on your canvas:
def drawCircle():
...
shape = my_canvas1.create_oval(x1, y1, x1 + diameter, y1 + diameter+20, fill=color)
frame = tk.Frame(my_canvas1)
game1_button = tk.Button(frame, text = "Green")
game1_button.grid(row= 8, column = 3)
game1_button["command"] = lambda: messagebox.showinfo("Congratulations!", "Correct Answer!")
game2_button = tk.Button(frame, text = "Blue")
game2_button.grid(row= 8, column = 5)
game2_button["command"] = lambda: messagebox.showinfo("Sorry!", "Incorrect Answer!")
game3_button = tk.Button(frame, text = "Red")
game3_button.grid(row= 8, column = 7)
game3_button["command"] = lambda: messagebox.showinfo("Sorry", "Incorrect Answer!")
my_canvas1.create_window(200,500,window=frame)
And of course, add win.mainloop() to the bottom of your program if you haven't already.

Creating Tkinter Text boxes and inserting into a dictionary

I have a long chunk of code. I do not want to paste it all here, so let me explain what I am trying to accomplish here. Based on a number provided by the user I want to create that many text boxes and then get what is entered into that text box and insert that into the dictionary. I have tried this a few ways and just cannot get it to work correctly. The list is either empty or it only contains the last text box as the value for each key.
def multiple_choice():
def add():
top.destroy()
top = Tk()
top.title("Add Question")
w = 800
h = 800
ws = top.winfo_screenwidth()
hs = top.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
top.geometry('%dx%d+%d+%d' % (w, h, x, y))
question = Label(top, text="Question to be asked?", font = "Times 14 bold", fg = "blue")
question.grid(row = 2, column = 4)
questionText = Text(top, borderwidth = 5, width=50,height=5, wrap=WORD, background = 'grey')
questionText.grid(row = 3, column = 4)
numQuestions = Label(top, text = "Number of answer choices?", font = "Times 14 bold", fg = "blue")
numQuestions.grid(row = 4, column=4)
num = Entry(top, bd = 5)
num.grid(row=5, column = 4)
answerList = {}
def multiple():
def preview():
preview = Tk()
top.title("Question Preview")
w = 500
h = 500
ws = top.winfo_screenwidth()
hs = top.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
top.geometry('%dx%d+%d+%d' % (w, h, x, y))
title = Label(preview, text = "Short Answer Question Preview", font = "Times 18 bold", fg = "blue" )
title.grid(row = 0, column = 2)
qtext = "Question text will read: "
ques = Label(preview, text = qtext)
ques.grid(row=1, column = 2)
ques2 = Label( preview, text = questionText.get("1.0",END))
let = 'A'
i = 1
for word in answerList:
prev = let + ": " + word
ans = Label(preview, text = prev)
ans.grid(row=1+i, column = 2)
let = chr(ord(let) + 1)
answerCor = "The correct answer(s): "
a = Label(preview, text = answerCor)
a.grid(row=4, column = 2)
b = Label(preview, text = cor.get)
b.grid(row=5, column = 2)
if num.get().isdigit():
number = int(num.get())
AnswerChoices = Label(top, text = "Answer Choices?", font = "Times 14 bold", fg = "blue")
AnswerChoices.grid(row = 6, column=4)
i = 0
let = 'A'
while i < number:
letter = Label(top, text = let)
letter.grid(row = 8+(i*4), column = 3)
answer = Text(top, borderwidth = 5, width=50, height=3, wrap=WORD, background = 'grey')
answer.grid(row = 8+(i*4), column = 4)
answerList[let] = answer.get("1.0",END)
i = i+1
let = chr(ord(let) + 1)
print answerList
correct = Label(top, text = "Correct Answer(s) (seperated by commas)",
font = "Times 14 bold", fg = "blue")
correct.grid(row =99 , column=4)
cor = Text(top, borderwidth = 5, width=50, height=3, wrap=WORD, background = 'grey')
cor.grid(row=100, column = 4)
else:
error = Tk()
w = 500
h = 100
ws = top.winfo_screenwidth()
hs = top.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
error.geometry('%dx%d+%d+%d' % (w, h, x, y))
text = "ERROR: You must enter an integer number"
Label(error,text = text, fg = "red", font = "Times 16 bold").pack()
MyButton5 = Button(top, text="Preview Question", width=20, command = preview, anchor=S)
MyButton5.grid(row=102, column=5)
MyButton4 = Button(top, text="Finish and Add Question", width=20, command = add, anchor=S)
MyButton4.grid(row=102, column=2)
but = Button(top, text="Submit", width=10, command = multiple)
but.grid(row=6, column = 4)
top.mainloop()
def button():
MyButton21 = Button(quiz, text="Short Answer Question", width=20, command = short_answer)
MyButton21.grid(row=8, column=2)
MyButton22 = Button(quiz, text="True/False Question", width=20, command = true_false)
MyButton22.grid(row=8, column=4)
MyButton23 = Button(quiz, text="Multiple Choice Question", width=20, command = multiple_choice)
MyButton23.grid(row=9, column=2)
#MyButton24 = Button(quiz, text="Matching Question", width=20, command = matching)
#MyButton24.grid(row=9, column=4)
MyButton25 = Button(quiz, text="Ordering Question", width=20, command =order)
MyButton25.grid(row=10, column=2)
MyButton26 = Button(quiz, text="Fill in the Blank Question", width=20, command = fill_blank)
MyButton26.grid(row=10, column=4)
MyButton3 = Button(quiz, text="Finsh Quiz", width=10, command = quiz)
MyButton3.grid(row=12, column=3)
quiz = Tk()
w = 700
h = 300
ws = quiz.winfo_screenwidth()
hs = quiz.winfo_screenheight()
x = 0
y = 0
quiz.geometry('%dx%d+%d+%d' % (w, h, x, y))
quiz.title("eCampus Quiz Developer")
L1 = Label(quiz, text="Quiz Title?")
L1.grid(row=0, column=0)
E1 = Entry(quiz, bd = 5)
E1.grid(row=0, column=3)
name_file = E1.get()
name_file = name_file.replace(" ", "")
name_file = name_file + ".txt"
with open(name_file,"w") as data:
MyButton1 = Button(quiz, text="Submit", width=10, command = button)
MyButton1.grid(row=1, column=3)
quiz.mainloop()
I am trying to create the dictionary using this chunk of code:
i = 0
let = 'A'
while i < number:
letter = Label(top, text = let)
letter.grid(row = 8+(i*4), column = 3)
answer = Text(top, borderwidth = 5, width=50, height=3, wrap=WORD, background = 'grey')
answer.grid(row = 8+(i*4), column = 4)
answerList[let] = answer.get("1.0",END)
i = i+1
let = chr(ord(let) + 1)
I have even tried putting a loop in the preview function but that is when the last box was the only value contained in the dictionary. Any ideas would be appreciated
Please see my commeneted snippet below which demonstrates this:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.entry = Entry(self.root) #entry to input number of entries later
self.button = Button(self.root, text="ok", command=self.command) #calls command to draw the entry boxes
self.frame = Frame(self.root)
self.entry.pack()
self.button.pack()
self.frame.pack()
def command(self):
self.frame.destroy() #destroys frame and contents
self.frame = Frame(self.root) #recreates frame
self.text = [] #empty array to store entry boxes
for i in range(int(self.entry.get())):
self.text.append(Entry(self.frame, text="Question "+str(i))) #creates entry boxes
self.text[i].pack()
self.done = Button(self.frame, text="Done", command=self.dict) #button to call dictionary entry and print
self.done.pack()
self.frame.pack()
def dict(self):
self.dict = {}
for i in range(len(self.text)):
self.dict.update({self.text[i].cget("text"): self.text[i].get()})
#the above line adds a new dict entry with the text value of the respective entry as the key and the value of the entry as the value
print(self.dict) #prints the dict
root = Tk()
App(root)
root.mainloop()
The above asks the user how many entry widgets they want to create, fills a frame with those entry widgets and then iterates through the list which contains them on the press of a button, adding a new dictionary entry for each entry widget, where the key of the dict is the attribute text for each entry and the value of the dict is the value of each entry.

Discussion with tkinter

from tkinter import *
window = Tk()
ia_answers= "trolol"
input_frame = LabelFrame(window, text="User :", borderwidth=4)
input_frame.pack(fill=BOTH, side=BOTTOM)
input_user = StringVar()
input_field = Entry(input_frame, text=input_user)
input_field.pack(fill=BOTH, side=BOTTOM)
ia_frame = LabelFrame(window, text="Discussion",borderwidth = 15, height = 100, width = 100)
ia_frame.pack(fill=BOTH, side=TOP)
user_says = StringVar()
user_text = Label(ia_frame, textvariable=user_says, anchor = NE, justify = RIGHT, bg="white")
user_text.pack(fill=BOTH, side=TOP)
ia_says = StringVar()
ia_text = Label(ia_frame, textvariable=ia_says, anchor = W, justify = LEFT, bg="white")
ia_text.pack(fill=BOTH, side=BOTTOM)
def Enter_pressed(event):
"""Took the current string in the Entry field."""
input_get = input_field.get()
input_user.set("")
user_says.set(input_get + "\n\n")
ia_says.set(ia_answers)
input_field.bind("<Return>", Enter_pressed)
window.mainloop()
Hi, i am trying to build a discussion Bot.
When I execute the code, the question in the input field and the answer get displayed correctly.
The problem is after entering the next sentence, the previous question/answer gets removed. Here is an example:
Hello Bot
Hello User
(then the text disappears)
How are you
Fine thank you
What i want :
Hello Bot
Hello User
(then the text stays in the frame)
How are you
Fine thank you
The issue occurs in line -
user_says.set(input_get + "\n\n")
ia_says.set(ia_answers)
You are replace users_says.set() and ia_says.set() resets the complete Labels , with the new value. Instead you should get the old value and append the new value to it and set it back, Example -
user_says.set(user_says.get() + input_get + "\n")
ia_says.set(ia_says.get() + ia_answers + "\n")
Or you can also create a new label for each new event and add it to the LabelFrame . Example -
from tkinter import *
window = Tk()
ia_answers= "trolol\n"
input_frame = LabelFrame(window, text="User :", borderwidth=4)
input_frame.pack(fill=BOTH, side=BOTTOM)
input_user = StringVar()
input_field = Entry(input_frame, text=input_user)
input_field.pack(fill=BOTH, side=BOTTOM)
ia_frame = LabelFrame(window, text="Discussion",borderwidth = 15, height = 100, width = 100)
ia_frame.pack(fill=BOTH, side=TOP)
user_says = StringVar()
user_text = Label(ia_frame, textvariable=user_says, anchor = NE, justify = RIGHT,
bg="white")
user_text.pack(fill=X)
ia_says = StringVar()
ia_text = Label(ia_frame, textvariable=ia_says, anchor = NW, justify = LEFT, bg="white")
ia_text.pack(fill=X)
user_texts = []
ia_texts = []
user_says_list = []
ia_says_list = []
def Enter_pressed(event):
"""Took the current string in the Entry field."""
input_get = input_field.get()
input_user.set("")
user_says1 = StringVar()
user_says1.set(input_get + "\n")
user_text1 = Label(ia_frame, textvariable=user_says1, anchor = NE, justify = RIGHT,
bg="white")
user_text1.pack(fill=X)
user_texts.append(user_text1)
user_says_list.append(user_says1)
ia_says1 = StringVar()
ia_says1.set(ia_answers)
ia_text1 = Label(ia_frame, textvariable=ia_says1, anchor = NW, justify = LEFT,
bg="white")
ia_text1.pack(fill=X)
ia_texts.append(ia_text1)
ia_says_list.append(ia_says1)
input_field.bind("<Return>", Enter_pressed)
window.mainloop()

Categories