The problem is idk how to make a vertical style multiple choice question quiz asking for the capitals of countries and allowing for a multiple choice to choose the correct country. I currently have made a welcome home frame for asking for the users name and age to enter my quiz and I'm stuck on how to write the code for the next frame. I have attached screenshots below at how I want the multiple choice quiz to be similar to my first frame where the question and multiple choice is underneath the black and white title label named Quiz Question, I want to try and make a second frame containing the multiple choice question that can be accessed from a radio button named next from the first frame code I have shown below.
from tkinter import*
from tkinter import ttk
class CapitalQuiz:
def __init__(self,parent):
'''Widgets for Welcome Frame'''
self.Welcome = Frame(parent)
self.Welcome.grid(row=0, column=0)
self.TitleLabel = Label(self.Welcome, text = "Welcome to Capital Quiz",
bg = "black", fg = "white", width = 20, padx = 30, pady = 10, font = ("Time", '14', "bold italic"))
self.TitleLabel.grid(columnspan = 2)
#Name and Age Labels
self.NameLabel = Label(self.Welcome, text = "Name", anchor = W,
fg = "black", width = 10, padx = 30, pady = 10, font = ("Time", '12', "bold italic"))
self.NameLabel.grid(row = 2, column = 0)
self.AgeLabel = Label(self.Welcome, text = "Age", anchor = W,
fg = "black", width = 10, padx = 30, pady = 10, font = ("Time", '12', "bold italic"))
self.AgeLabel.grid(row=3, column = 0)
#Name and Age Entry
self.NameEntry = ttk.Entry(self.Welcome, width = 20)
self.NameEntry.grid(row=2, column = 1, columnspan = 2)
self.AgeEntry = ttk.Entry(self.Welcome, width = 20)
self.AgeEntry.grid(row = 3, column = 1)
#Difficulty level label and radio buttons
self.WarningLabel = Label(self.Welcome, text = "", anchor=W, fg = "red", width = 20, padx = 30, pady = 10)
self.WarningLabel.grid(row=4, columnspan = 2)
self.DifficultyLabel = Label(self.Welcome, text = "Choose Difficulty level", anchor=W, fg = "black", width = 10, padx = 30, pady = 10, font = ("Time", '12',"bold italic"))
self.DifficultyLabel.grid(row=5, column = 0)
self.difficulty = ["Easy", "Medium", "Hard"]
self.diff_lvl = StringVar()
self.diff_lvl.set(0)
self.diff_btns = [ ]
for i in range(len(self.difficulty)):
self.rb = Radiobutton(self.Welcome, variable = self.diff_lvl, value = i, text = self.difficulty[i], anchor = W, padx = 50, width = "5", height = "2")
self.diff_btns.append(self.rb)
self.rb.grid(row = i+6, column = 0, sticky = W)
'''Widgets for Question Frame'''
self.Questions = Frame(parent)
self.QuestionsLabel = Label(self.Questions, text = "Quiz Questions", bg = "black", fg = "white", width = 20, padx = 30, pady = 10,font = ("Time", '14', "bold italic"))
self.QuestionsLabel.grid(columnspan = 2)
self.HomeButton = ttk.Button(self.Questions, text = 'Home', command = self.show_Welcome)
self.HomeButton.grid(row = 8, column = 1)
'''A Method that removes Questions Frame'''
def show_Welcome(self):
self.Questions.grid_remove()
self.Welcome.grid()
def show_Questions(self):
try:
if self.NameEntry.get() == "":
self.WarningLabel.configure(text = "Please enter name")
self.NameEntry.focus()
elif self.NameEntry.get().issalpha() == False:
self.WarningLabel.configure(text = "Please enter text")
self.NameEntry.delete(0, END)
self.NameEntry.focus()
elif self.AgeEntry.get() == "":
self.WarningLabel.configure(text = "Please enter age")
self.AgeEntry.focus()
elif int(self.AgeEntry.get()) > 12:
self.WarningLabel.configure(text = "You are too old!")
self.AgeEntry.delete(0, END)
self.AgeEntry.focus()
elif int(self.AgeEntry.get()) < 0:
self.WarningLabel.configure(text = "You are too old")
self.AgeEntry.delete(0, END)
self.AgeEntry.focus()
elif int(self.AgeEntry.get()) < 7:
self.WarningLabel.configure(text = "You are too young")
self.AgeEntry.delete(0, END)
self.AgeEntry.focus()
else:
self.Welcome.grid_remove()
self.Questions.grid()
except ValueError:
self.WarningLabel.configure(text = "Please enter a number")
self.AgeEntry.delete(0, END)
self.AgeEntry.focus()
I reviewed your code and your requirements for your program CapitalQuiz. I made some changes in code you attach. I change the method of the showing Titletext because according to your method you have to create label everytime to show Titletext when you switch the frames between because the TitleLabel is the part of the Welcome frame
self.TitleLabel = Label(self.Welcome, text = "Welcome to Capital
Quiz",bg = "black", fg = "white", width = 20, padx = 30, pady = 10,
font = ("Time", '14', "bold italic"))
self.TitleLabel.grid(columnspan = 2)
I remove it from Welcome frame & pack it in parent with Welcome frame so now we only have to change the frame to QuestionFrame to swich between. Also i created function called setTitleLabelText to set Titlelabel text using textvarible anytime & anywhere.
I wrote the method to switch to Questions Frame and change Title to "Questions". For switch to Questions frame we a need button but you had not created so i create one called Start Quiz in Welcome Frame. I have not write the code to load a question i have only write the code to switch to a questions frame and from questions frame to Welcomr frame.
Here's the code.
from tkinter import*
from tkinter import ttk
class CapitalQuiz:
def __init__(self,parent):
'''Title Label. I remove it from welcome frame cause ,
when we change the frame we have to again create another label to show other title which is make program slow
I pack it in parent window with welcome frame and asign tkinter StringVar so we can change it anytime
from anywhere with function'''
self.Titletext = StringVar()
self.TitleLabel = Label(parent, textvariable=self.Titletext,
bg = "black", fg = "white", width = 20, padx = 30, pady = 10, font = ("Time", '14', "bold italic"))
self.TitleLabel.pack(side="top",fill="x")
#Function to set TitleLabelText
self.setTitleLabeltext("Welcome to CapitalQuiz")
#Welcome Frame
self.Welcome = Frame(parent)
self.Welcome.pack(fill="both")
'''Widgets for Welcome Frame'''
#Name and Age Labels
self.NameLabel = Label(self.Welcome, text = "Name", anchor = W,
fg = "black", width = 10, padx = 30, pady = 10, font = ("Time", '12', "bold italic"))
self.NameLabel.grid(row = 2, column = 0)
self.AgeLabel = Label(self.Welcome, text = "Age", anchor = W,
fg = "black", width = 10, padx = 30, pady = 10, font = ("Time", '12', "bold italic"))
self.AgeLabel.grid(row=3, column = 0)
#Name and Age Entry
self.NameEntry = ttk.Entry(self.Welcome, width = 20)
self.NameEntry.grid(row=2, column = 1, columnspan = 2)
self.AgeEntry = ttk.Entry(self.Welcome, width = 20)
self.AgeEntry.grid(row = 3, column = 1)
#Difficulty level label and radio buttons
self.WarningLabel = Label(self.Welcome, text = "", anchor=W, fg = "red", width = 20, padx = 30, pady = 10)
self.WarningLabel.grid(row=4, columnspan = 2)
self.DifficultyLabel = Label(self.Welcome, text = "Choose Difficulty level", anchor=W, fg = "black", width = 10, padx = 30, pady = 10, font = ("Time", '12',"bold italic"))
self.DifficultyLabel.grid(row=5, column = 0)
self.difficulty = ["Easy", "Medium", "Hard"]
self.diff_lvl = StringVar()
self.diff_lvl.set(0)
self.diff_btns = [ ]
for i in range(len(self.difficulty)):
self.rb = Radiobutton(self.Welcome, variable = self.diff_lvl, value = i, text = self.difficulty[i], anchor = W, padx = 50, width = "5", height = "2")
self.diff_btns.append(self.rb)
self.rb.grid(row = i+6, column = 0, sticky = W)
'''A button to switch to Questions Frame'''
row = len(self.difficulty)
self.StartQuizButton = ttk.Button(self.Welcome, text = 'Start Quiz',command=self.show_Questions)
self.StartQuizButton.grid(row = row+6, column = 0,pady=5,columnspan=3)
'''Widgets for Question Frame'''
self.Questions = Frame(parent)
self.QuestionsLabel = Label(self.Questions, text = "Quiz Questions", bg = "black", fg = "white", width = 20, padx = 30, pady = 10,font = ("Time", '14', "bold italic"))
self.QuestionsLabel.pack(fill="both")
self.QuestionsLabel.pack_forget()
self.HomeButton = ttk.Button(self.Questions, text = 'Home',command=self.showWelcomeFrame)
self.HomeButton.grid(row = 8, column = 0,columnspan=3)
# '''A Method that removes Questions Frame'''
def setTitleLabeltext(self,text):
# This method can be use in class multiple times so,
# we dont have to make individual function everytime to show TitleText
self.Titletext.set(text)
def showQuestionFrame(self):
self.Welcome.pack_forget()
self.Questions.pack(fill="both")#Here we have to specify the pack values again becuase we called pack_forget befor
self.setTitleLabeltext("Questions")
def showWelcomeFrame(self):
self.Questions.pack_forget()
self.Welcome.pack(fill="both")#Here we have to specify the pack values again becuase we called pack_forget before
self.setTitleLabeltext("Welcome to CapitalQuiz")
self.NameEntry.delete(0,"end")
self.AgeEntry.delete(0,"end")
def show_Questions(self):
try:
if self.NameEntry.get() == "":
self.WarningLabel.configure(text = "Please enter name")
self.NameEntry.focus()
elif self.NameEntry.get().isalpha() == False:
self.WarningLabel.configure(text = "Please enter text")
self.NameEntry.delete(0, END)
self.NameEntry.focus()
elif self.AgeEntry.get() == "":
self.WarningLabel.configure(text = "Please enter age")
self.AgeEntry.focus()
elif int(self.AgeEntry.get()) > 12:
self.WarningLabel.configure(text = "You are too old!")
self.AgeEntry.delete(0, END)
self.AgeEntry.focus()
elif int(self.AgeEntry.get())
Related
I started working with tkinter recently and I have the following problem, I need to make the check box bigger but that is only possible with adding an image. The problem is that whenever I add an image to a button it becomes unclickable and the image is not displayed, here is my source code (part of a bigger project). My goal is to display some information and let the user decide which option he gets to keep using the check button. Any help is appreciated.
import tkinter as tk
import tkcalendar as tkc
LARGE_FONT = ("HELVETICA", 32, 'bold')
NORMAL_FONT = ("calibri", 18)
class ConstituireDosar(tk.Toplevel):
def __init__(self, controller):
tk.Toplevel.__init__(self)
self.update_idletasks()
# self.dosar = dosar
self.controller = controller
self.minsize(651, 569)
# self.maxsize(651, 569)
frame_titlu = tk.Frame(self)
frame_titlu.grid(row = 0, column = 0)
frame_continut = tk.Frame(self)
frame_continut.grid(row = 1, column = 0, sticky = "w")
frame_acte = tk.Frame(self)
frame_acte.grid(row = 2, column = 0)
titlu = tk.Label(frame_titlu, font = LARGE_FONT, text = "Constituire Dosar")
titlu.grid(row = 0 , column = 0, padx = 10, pady = 15)
data_emiterii = tk.Label(frame_continut, font = NORMAL_FONT,text = "Data emiterii documentului:")
data_emiterii.grid(row = 1, column = 0, padx = 10, pady = 5, sticky = "w")
self.cal = tkc.DateEntry(frame_continut, date_pattern = "DD/MM/YYYY", width = 20)
self.cal.grid(row = 2, column = 0, padx = 10, pady = 5, sticky = "w")
debitori_label = tk.Label(frame_continut, font = NORMAL_FONT, text = "Selecteaza debitorii.")
debitori_label.grid(row = 3, column = 0, padx = 10, pady = 5, sticky = "w")
debitori = []
tip_debitori = []
for i in range(2):
debitori.append("Person %s " % str(i))
tip_debitori.append("Person %s type" % str(i))
for i in range(len(debitori)):
print(debitori[i])
row_i = 4
self.vars_debitori = []
on_image = tk.PhotoImage(width=48, height=24)
off_image = tk.PhotoImage(width=48, height=24)
on_image.put(("green",), to=(0, 0, 23,23))
off_image.put(("red",), to=(24, 0, 47, 23))
for i in range(len(debitori)):
var = tk.IntVar(frame_continut, value = 0)
interior = debitori[i] + " - " + tip_debitori[i]
# Checkbutton(ws, image=switch_off, selectimage=switch_on, onvalue=1, offvalue=0, variable=cb1, indicatoron=False, command=switchState)
checkbuton = tk.Checkbutton (frame_continut, bd = 5, image = off_image, selectimage = on_image, indicatoron = False, onvalue = 1, offvalue = 0, variable = var, state = tk.ACTIVE, command = lambda: self.toggle(var))
checkbuton.grid(row = row_i, column = 0, padx = 20, pady = 5, sticky = "nw")
checkbuton.image = off_image
# checkbuton.select()
self.vars_debitori.append(var)
row_i += 1
self.vars_acte = []
acte = ["Acte de Procedura", "Incheiere de Admitere", "Cerere de Incuviintare", "Instiintare Creditor"]
for i in range(4):
v = tk.IntVar()
check = tk.Checkbutton(frame_acte, font = NORMAL_FONT, text = acte[i], variable = v)
check.grid(row = row_i, column = 0, padx = 10, pady = 5)
check.select()
self.vars_acte.append(v)
row_i += 1
emite_acte = tk.Button(frame_acte, font = NORMAL_FONT, text = "Emite acte.", command = self.emite_acte)
emite_acte.grid(row = row_i, column = 1, padx = 15, pady = 30, ipadx = 70, ipady = 10)
emite_acte.configure(bg = '#218838', fg = '#FFFFFF')
buton_cancel = tk.Button(frame_acte, font = NORMAL_FONT, text = "Cancel", command = lambda: self.destroy())
buton_cancel.grid(row = row_i, column = 0, padx = 15, pady = 30, ipadx = 70, ipady = 10)
buton_cancel.configure(bg = "red", fg = '#FFFFFF')
def emite_acte(self):
print(self.cal.get_date().strftime("%d/%m/%y"))
print(self.winfo_height(), self.winfo_width())
if __name__ == "__main__":
root = tk.Tk()
app = ConstituireDosar(root)
app.protocol("WM_DELETE_WINDOW", root.destroy)
root.withdraw()
root.mainloop()
I tried some options that I saw on the forum, in another file they worked fine but when I tried to implement it in the project itself the checkbutton is still unclickable and it doesn't display the images either. tkinter checkbutton different image I tried to replicate Bryan's answer, but no luck there. Also didn't receive any console error message.
As #furas pointed in the comments above, the problem got fixed with keeping the images as member variables of the class, also the button became clickable after removing the self.toggle(var) command from checkbutton
I have written the following code to get the user input. But I am not able to add a scrollbar to it. I want to place a vertical scrollbar because I am not able to view all the input labels on my screen.
I first tried:
v = Scrollbar(root, orient='vertical')
v.config(command=root.yview)
It gave me the following error:
File "/Users/aaditya/Desktop/Blender_software/Blender_algo_exp/testing.py", line 235, in <module>
label1.grid(row = 1, column = 0, padx = 10, pady = 10)
File "/opt/anaconda3/envs/blender_env/lib/python3.9/tkinter/__init__.py", line 2486, in grid_configure
self.tk.call(
_tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack
After that I tried the following:
myscroll = Scrollbar(root)
myscroll.pack(side = RIGHT, fill = Y)
Which resulted in the following error:
AttributeError: '_tkinter.tkapp' object has no attribute 'yview'
How can I fix this?
This is my entire code:
# Driver code
if __name__ == "__main__" :
root = Tk()
# v = Scrollbar(root, orient='vertical')
# v.config(command=root.yview)
# myscroll = Scrollbar(root)
# myscroll.pack(side = RIGHT, fill = Y)
root.configure(background = 'light gray')
root.geometry("700x700")
root.title("Blender Software")
label1 = Label(root, text = "Total Quantity: ",
fg = 'black', bg = 'white')
label2 = Label(root, text = "Percentage of Solid Scrap : ",
fg = 'black', bg = 'white')
label3 = Label(root, text = "Cr min : ",
fg = 'black', bg = 'white')
label4 = Label(root, text = "Cr max : ",
fg = 'black', bg = 'white')
label1.grid(row = 1, column = 0, padx = 10, pady = 10)
label2.grid(row = 2, column = 0, padx = 10, pady = 10)
label3.grid(row = 3, column = 0, padx = 10, pady = 10)
label4.grid(row = 4, column = 0, padx = 10, pady = 10)
# Create a entry box
# for filling or typing the information.
total_quantity = Entry(root)
per_solid_scrap = Entry(root)
Cr_min_input = Entry(root)
Cr_max_input = Entry(root)
# grid method is used for placing
# the widgets at respective positions
# in table like structure .
total_quantity.grid(row = 1, column = 1, padx = 10, pady = 10)
per_solid_scrap.grid(row = 2, column = 1, padx = 10, pady = 10)
Cr_min_input.grid(row = 3, column = 1, padx = 10, pady = 10)
Cr_max_input.grid(row = 4, column = 1, padx = 10, pady = 10)
button1 = Button(root, text = "Submit", bg = "red",
fg = "black", command = calculate_op)
button1.grid(row = 21, column = 1, pady = 10)
# Start the GUI
root.mainloop()
Pack and grid cannot be used at the same time. So since you called the pack for the scrollbar, you cannot manage the following widgets by grid anymore. An easy fix is to place the scrollbar with grid function instead. Apart from that, try using a function or class to make your code less lengthy because now it seems hard to read and purposeless.
I am attempting to create a relatively simple survey like form in Tkinter, and I'm relatively new to the GUI framework. I'm having real issues trying to figure out why there are so many inconsistencies, especially when working with grid placement+frames+multiple widgets in same row. Especially this specific example. I'm tying together all my questions into a single frame, and it seems to work out... sort of half. Though the rows seem to cooperate nicely, the columns are where the whole thing gets erupted.
qframe1 = Frame(question, bg='black')
qframe1.grid(row=1, padx = 20, sticky = W)
q1l = Label(qframe1, text = 'Question 1: How often do you eat at Mcdonalds?', font = ('Calibri', 14), bg = 'azure')
q1l.grid(columnspan = 4, pady = 5, sticky = W)
q1 = StringVar()
q1.set('None')
q1r1 = Radiobutton(qframe1, text = 'Everyday!', font = ('Calibri', 12), bg = 'azure', variable = q1, value = 'Always')
q1r1.grid(row=1, column = 0, pady = 5, sticky = W)
q1r2 = Radiobutton(qframe1, text = 'Sometimes', font = ('Calibri', 12), bg = 'azure', variable = q1, value = 'Sometimes')
q1r2.grid(row=1, column = 1, pady = 5, sticky = W)
q1r3 = Radiobutton(qframe1, text = 'Not Frequently', font = ('Calibri', 12), bg = 'azure', variable = q1, value = 'Infrequent')
q1r3.grid(row=1, column = 2, pady = 5, sticky = W)
q1r4 = Radiobutton(qframe1, text = 'Never', font = ('Calibri', 12), bg = 'azure', variable = q1, value = 'Never')
q1r4.grid(row=1, column = 3, pady = 5, sticky = W)
This is the bare code for the section that's messing up.
Also, I have made sure that it's not the length of each radio button that is causing the issue. When I change the text of the radio buttons, they still get placed in the same irregular positions.
Here's the code for another section of the trivia.
q2l = Label(qframe1, text = 'Question 2: What meal do you normally order?', font = ('Calibri', 14), bg = 'azure')
q2l.grid(row=2, columnspan = 4, pady = 5, sticky = W)
q2 = StringVar()
q2.set('None')
q2r1 = Radiobutton(qframe1, text = 'Fries', font = ('Calibri', 12), bg = 'azure', variable = q2, value = 'Fries')
q2r1.grid(row=3, column = 0, pady = 5, sticky = W)
q2r2 = Radiobutton(qframe1, text = 'Hamburgers', font = ('Calibri', 12), bg = 'azure', variable = q2, value = 'Hamburgers')
q2r2.grid(row=3, column = 1, pady = 5, sticky = W)
q2r3 = Radiobutton(qframe1, text = 'Chicken Nuggets', font = ('Calibri', 12), bg = 'azure', variable = q2, value = 'Chicken Nuggets')
q2r3.grid(row=3, column = 2, pady = 5, sticky = W)
q2r4 = Radiobutton(qframe1, text = 'Coffee', font = ('Calibri', 12), bg = 'azure', variable = q2, value = 'Coffee')
q2r4.grid(row=3, column = 3, pady = 5, sticky = W)
This again causes an irregular spacing. But this time, the spacing is completely different from the radio buttons in question 1. And rinse and repeat with every new question set of radio buttons.
There are no issues with the buttons on the right side. Perhaps it's because they're aligned in rows and not columns which are causing the spacing issue.
bframe = Frame(question, bg='black')
bframe.grid(row=1, padx = 20, sticky = E)
audioq1 = Button(bframe, text = ' Listen to Audio', font = ('Calibri', 14), bg = 'brown1', fg = 'azure', image = sound, relief = SUNKEN, compound = LEFT, command = q1audio)
audioq1.grid(ipadx = 5, pady = 20)
audioq2 = Button(bframe, text = ' Listen to Audio', font = ('Calibri', 14), bg = 'brown1', fg = 'azure', image = sound, relief = SUNKEN, compound = LEFT, command = q2audio)
audioq2.grid(row = 1, ipadx = 5, pady = 20)
audioq3 = Button(bframe, text = ' Listen to Audio', font = ('Calibri', 14), bg = 'brown1', fg = 'azure', image = sound, relief = SUNKEN, compound = LEFT, command = q3audio)
audioq3.grid(row = 2, ipadx = 5, pady = 20)
audioq4 = Button(bframe, text = ' Listen to Audio', font = ('Calibri', 14), bg = 'brown1', fg = 'azure', image = sound, relief = SUNKEN, compound = LEFT, command = q4audio)
audioq4.grid(row = 3, ipadx = 5, pady = 20)
audioq5 = Button(bframe, text = ' Listen to Audio', font = ('Calibri', 14), bg = 'brown1', fg = 'azure', image = sound, relief = SUNKEN, compound = LEFT, command = q5audio)
audioq5.grid(row = 4, ipadx = 5, pady = 20)
Any help would be greatly appreciated!
If, as mentioned in the comments, "weight isn't necessarily the problem", the placement of the radiobuttons can be realized using pack instead of grid.
This gives something like this (on a mac):
If you want a more evenly placed buttons to fill the available width, you can achieve this with grid:
I also rewrote a portion of the code to make it easier to add questions to the form. Each question is now in its own frame, allowing for more flexibility.
import tkinter as tk
class QFrame(tk.Frame):
id = 1
def __init__(self, master, question):
self.master = master
super().__init__(self.master)
self.id = QFrame.id
QFrame.id += 1
self.q = tk.StringVar()
self.q.set('None')
self.question, self.choices = question
self.q_label = tk.Label(self, text=f'Question {self.id}: {self.question}')
self.q_label.pack(expand=True, anchor=tk.W)
self.choose = []
for idx, choice in enumerate(self.choices):
txt, value = choice
qr = tk.Radiobutton(self, text=txt, variable=self.q, value=value)
self.choose.append(qr)
qr.pack(side=tk.LEFT)
class App(tk.Tk):
def __init__(self, questions):
self.questions = questions
super().__init__()
for question in questions:
self.qframe = QFrame(self, question)
self.qframe.pack(fill=tk.X)
q1 = ['How often do you eat at Mcdonalds?',
(('Everyday!', 'Always'),
('Sometimes', 'Sometimes'),
('Not Frequently', 'Infrequent'),
('Never', 'Never'))]
q2 = ['What meal do you normally order?',
(('Fries!', 'Fries'),
('Hamburgers', 'Hamburgers'),
('Chicken Nuggets', 'Chicken Nuggets'),
('Coffee', 'Coffee'))]
q3 = ['how large is your usual party?',
(('alone!', 'alone'),
('two', 'two'),
('less than 5', 'less than 5'),
('5 or more', '5 or more'))]
questions = [q1, q2, q3]
app = App(questions)
app.mainloop()
The code for grid geometry manager:
class QFrame(tk.Frame):
id = 1
def __init__(self, master, question):
self.master = master
super().__init__(self.master)
self.id = QFrame.id
QFrame.id += 1
self.q = tk.StringVar()
self.q.set('None')
self.question, self.choices = question
self.grid_rowconfigure(0, weight=1)
for idx in range(4):
self.grid_columnconfigure(idx, weight=1)
self.q_label = tk.Label(self, text=f'Question {self.id}: {self.question}')
self.q_label.grid(row=0, column=0, columnspan=4, sticky="w")
self.choose = []
for idx, choice in enumerate(self.choices):
txt, value = choice
qr = tk.Radiobutton(self, text=txt, variable=self.q, value=value)
self.choose.append(qr)
qr.grid(row=1, column=idx, columnspan=1, sticky="ew")
So this is a basic clock and alarm that i am creating, and in the process i want the user to type in what hour and minute they want to set for the alarm. But the entry widget here is not responding.
import time
import tkinter as tk
current_date, current_time = 0, 0
def current_info(timeinfo): #function to get the current time and date
global current_date, current_time
# current time
current_time = time.strftime('%H:%M:%S')
current_date = time.strftime(r'%m/%d/%Y')
clock.after(200, timeinfo)
#Initialise the window
clock = tk.Tk()
clock.title('Easy CLock')
clock.configure(bg='#121212')
clock.columnconfigure(0, weight = 1)
clock.columnconfigure(1, weight = 1)
clock.columnconfigure(2, weight = 1)
clock.columnconfigure(3, weight = 1)
border_effects = {
"flat": tk.FLAT,
"sunken": tk.SUNKEN,
"raised": tk.RAISED,
"groove": tk.GROOVE,
"ridge": tk.RIDGE,
}
#Logo will be under the main parent
logo = tk.PhotoImage(file = r'C:\Users\User\VSC\Alarm\Logo1.png')
logo_size = logo.subsample(5)
#Time and Date function
def time_date():
current_info(time_date)
#Displays the time
c_time = tk.Label(f_time, text = current_time, fg='white', bg='#121212', font=('Verdana', 30))
c_date = tk.Label(f_time, text = current_date, font=('Verdana', 10), fg='white', bg='#121212')
c_time.grid(column=0, row=0)
c_date.grid(column=0, row=1)
#alarm button command
def alarm_func():
current_info(alarm_func)
c_time = tk.Label(f_alarm, text = current_time, fg='white', bg='#121212', font=('Verdana', 10))
c_date = tk.Label(f_alarm, text = current_date, font=('Verdana', 10), fg='white', bg='#121212')
def pressed_enter(): #Command for the enter button
set_label = tk.Label(f_alarm, text = f'Alarm has been set for {time_set}', fg ='white', bg = '#121212', borderwidth = 1, relief = border_effects['sunken'])
set_label.grid(column = 4, row = 0, sticky = 'W')
# Set the time and date for the alarm
set_time = tk.StringVar()
alarm_entry = tk.Entry(clock, textvariable = set_time)
set_time.set('H : M')
time_set = alarm_entry.get()
#label and entry to set alarm / Enter Button
c_label = tk.Label(f_alarm, text = 'Set Alarm: ', font = ('Verdana', 10), fg= 'white', bg ='#121212' )
alarm_enter = tk.Button(f_alarm, text = 'Enter', font = ('Verdana', 7), width = 5, command = pressed_enter)
#Pack the widgets
c_time.grid(row = 0, column = 0)
c_date.grid(column = 1 , row = 0)
alarm_enter.grid(row = 2, column = 3)
c_label.grid(row = 2, sticky = 'W')
alarm_entry.grid(row = 2, column = 1)
#configure the empty columns
f_alarm.columnconfigure(2, minsize = 10)
def recall_frame(event):
if event == f_alarm:
event.grid_forget()
f_time.grid(column=0, row =1, columnspan = 4, sticky = 'N')
elif event == f_time:
event.grid_forget()
f_alarm.grid(column=0, row=1, columnspan = 4, sticky = 'W')
def back_func():
pass
#Creating Frames
f_time = tk.Frame(clock) #Clock Button
f_alarm = tk.Frame(clock) #Alarm Buttton
#configure the frames
f_time.configure(bg = '#121212')
f_alarm.configure(bg = '#121212')
#Setting label in the frame
f_lbl = tk.Label(clock, text= ' Simplistic Clock', image = logo_size, font=('Verdana', 30), fg='white', bg='#121212', compound = tk.LEFT, padx = 35)
time_but = tk.Button(clock, text='Clock', command= lambda :[time_date(), recall_frame(f_alarm)], bg='#f39c12', relief = border_effects['ridge'], pady = 7)
alarm_but = tk.Button(clock, text = 'Alarm', command = lambda :[alarm_func(), recall_frame(f_time)], bg='#f39c12', relief = border_effects['ridge'], pady = 7)
quit_but = tk.Button(clock, text='Exit', command = clock.quit, bg='#f39c12', relief = border_effects['ridge'], pady = 7)
back_but = tk.Button(clock, text = 'Back ', command = back_func, bg='#f39c12', relief = border_effects['ridge'], pady = 7)
f_lbl.config(borderwidth = 4, relief = border_effects['sunken'])
#Putting it on the frames
f_lbl.grid(column = 0, row = 0, columnspan = 5, sticky = 'EW')
time_but.grid(column = 0, row = 3, sticky = 'EW')
alarm_but.grid(column = 1, row = 3, sticky = 'EW')
quit_but.grid(column = 3, row = 3, sticky = 'EW')
back_but.grid(column = 2, row = 3, sticky = 'EW')
clock.mainloop()
i tried testing an entry widget outside the frame and the entry widget was able to work, is it because the frame f_alarm is not looping constantly in the background?
When someone clicks on your button which activates the pressed_enter() function, it will call that function again every time which will set the time to H:M and it will get that value as the set_time.get() is called immediately after.
You're also creating a new Entry every time the button is being clicked because you put alarm_entry = tk.Entry(clock, textvariable=set_time)
in there as well. You should only put the set_time.get inside of that button so that it gets the value that is currently filled in into the Entry. The other things like
set_time = tk.StringVar()
alarm_entry = tk.Entry(clock, textvariable=set_time)
set_time.set('H : M')
Should be put outside of that function so they don't get called every time someone clicks on the button.
from tkinter import *
from tkinter import ttk
import sqlite3
import os
import sys
import datetime
connection = sqlite3.connect("employees.db")
cursor = connection.cursor()
class Main(object):
def __init__(self, master):
self.master = master
#<-----Defining Frames----->
main_frame = Frame(self.master)
main_frame.pack()
top_frame = Frame(main_frame, width = 1250, height = 50, bg = '#f8f8f8', padx = 20, relief = SUNKEN, borderwidth = 1)
top_frame.pack(side = TOP, fill = X)
top_right_frame = Frame(top_frame, width = 100, height = 20, bg = '#f8f8f8', relief = SUNKEN, borderwidth = 0)
top_right_frame.pack(side = RIGHT)
center_frame = Frame(main_frame, width = 1350, height = 690, relief = RIDGE, bg = '#e6e6ff', borderwidth = 1)
center_frame.pack(side = TOP)
left_center_frame = Frame(center_frame, width = 180, height = 690, relief = SUNKEN, bg = '#e6e6ff', borderwidth = 1)
left_center_frame.pack(side = LEFT, fill = BOTH)
left_center_frame.pack_propagate(0)
right_center_frame = Frame(center_frame, width = 1170, height = 690, relief = SUNKEN, bg = '#e6e6ff', borderwidth = 1)
right_center_frame.pack()
right_center_frame.pack_propagate(0)
bottom_frame = Frame(main_frame, width = 1350, height = 10, relief = SUNKEN, bg = '#8080ff', borderwidth = 0)
bottom_frame.pack(side = BOTTOM, fill = X)
swap_type_frame = LabelFrame(left_center_frame, width = 250, height = 50, text = "Swap Type", bg = '#e6e6ff', padx = 5, pady = 5)
swap_type_frame.pack(side = TOP, fill = BOTH, padx = 5, pady = 5)
#<-----Defining Labels----->
label_main_title = Label(top_frame, text = "Advisor Roster Swap", bg = '#f8f8f8', font = ("TIMES",20), justify = CENTER)
label_main_title.pack()
label_current_day = Label(top_right_frame, text = timeDetails().current_date(), bg = '#f8f8f8', font = ("Times New Roman",10), anchor = NE)
label_current_day.pack(side = RIGHT)
label_bottom_frame = Label(bottom_frame, text = "© Vodafone WFM | RTA", font = ("Times New Roman",10), justify = CENTER, fg= '#ffffff', bg = '#8080ff' )
label_bottom_frame.pack(side = BOTTOM)
swap_type = ['One Way Swap', 'Two Way Swap', 'One Way CL Swap', 'Two Way CL Swap']
swap_type_combobox = ttk.Combobox(swap_type_frame, value = swap_type, width = 21)
swap_type_combobox.current(0)
swap_type_combobox.grid(row = 2, column = 1, pady = 5)
class Single_Advisor(object):
def __init__(self, master):
self.master = master
single_advisor_frame = LabelFrame(right_center_frame, width = 1150, height = 200, text = "Advisor Details", bg = '#e6e6ff', padx = 5, pady = 5)
single_advisor_frame.pack(side=TOP, fill=Y, padx = 5, pady = 5)
class Multiple_Advisors(object):
def __init__(self, master):
self.master = master
multiple_advisor_frame = LabelFrame(right_center_frame, width = 1150, height = 200, text = "Advisor Details", bg = '#e6e6ff', padx = 5, pady = 5)
multiple_advisor_frame.pack(side=TOP, fill=Y, padx = 5, pady = 5)
class timeDetails():
def current_date(self):
now = datetime.datetime.now()
return now.strftime("%A, %B %d")
def main():
root = Tk()
app = Main(root)
root.title("Advisor Roster Swap")
root.geometry("1350x750+350+200")
root.resizable(width = FALSE, height = FALSE)
root.mainloop()
if __name__ == '__main__':
main()
Hello, I want to hide/show frame and it's labels/widgets/boxes etc which will depend on the user selection in combo box. When selected, correct frame should appear which I have mentioned in class so that they can have one way swap or 2 way swap.
One way would have employee code boxes along with 7 boxes(shifts and offs) and 2 way will have 2 employee codes boxes along with 7X2 boxes for shifts and offs.