I am having a problem with adding status bar at the bottom of my program. When I do status.pack() it gives me this error : _tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack. In My (
def init(self): ) If I delete (self.grid(sticky = W+E+N+S) then the window pops up an then the status bar is on the window, but then the rest of the program isn't there. I was wondering if someone give some insight on how to fix this
from tkinter.constants import END
from tkinter import ttk
from tkinter import *
from tkinter import font
from tkinter import messagebox
import tkinter as tk
import turtle
import random
from tkinter import filedialog
from PIL import Image
class App(Frame):
**********************************************************************************************************************************************************************************************************************8888
'''The code below Creates a Menu Bar across the top of the window '''
App = Tk()
menu = Menu (App)
App.config(menu = menu)
'''Lines 20 - 22 are basic setup for drop down meun box at the top of the page.'''
fileMenu = Menu(menu, tearoff = 0)
fileMenu.add_command(label = "New Project", command = turtle)
fileMenu.add_command(label = "Open", command = turtle)
fileMenu.add_command(label = "Save", command = turtle)
fileMenu.add_command(label = "Save as", command = turtle)
fileMenu.add_command(label = "Close", command = turtle)
menu.add_cascade(label = "File", menu = fileMenu)
fileMenu.add_separator()
'''This bit of code adds a separator between the buttons on the drop down menu.'''
fileMenu.add_command(label = "Exit", command = App.quit)
editMenu = Menu(menu, tearoff = 0)
editMenu.add_command(label = "Cut", command = turtle)
editMenu.add_command(label = "Copy", command = turtle)
editMenu.add_command(label = "Paste", command = turtle)
editMenu.add_command(label = "Delete", command = turtle)
editMenu.add_command(label = "Select All", command = turtle)
menu.add_cascade(label = "Edit", menu = editMenu)
helpMenu = Menu(menu, tearoff = 0)
helpMenu.add_command(label = "Help Index", command = turtle)
helpMenu.add_command(label = "About", command = turtle)
menu.add_cascade(label = "Help", menu = helpMenu)
************************************************************************************************************************************************************************************************************************************
''' The code below creates a Status Bar Across the bottom of the page. '''
status = Label(App, text = "This is a status bar...", bd = 1, relief = SUNKEN, anchor = W)
status.pack()
******************************************************************************************************************************************************************************************************************************
def __init__(self):
'''Sets up the window and widgets.'''
Frame.__init__(self, bg = "white" ) #this sets the background color of the window.
self.master.title("Auto Body Buddy Estimator") #this is the title of the screen
self.master.geometry("600x600") #this is the specs for the window size
self.master.resizable(0, 0) #this makes the window none resizable
self.master.columnconfigure(0, weight = 1)
self.master.rowconfigure(0, weight = 1)
self.grid(sticky = W+E+N+S)
#!/usr/bin/python
'''import cgi, os
import cgitb; cgitb.enable()
form = cgi.FieldStorage()
# Get filename here.
fileitem = form['filename']
# Test if the file was uploaded
if fileitem.filename:
# strip leading path from file name to avoid
# directory traversal attacks
fn = os.path.basename(fileitem.filename)
open('/tmp/' + fn, 'wb').write(fileitem.file.read())
message = ('The file "' + fn + '" was uploaded successfully')
else:
message = 'No file was uploaded'
print """\
Content-Type: text/html\n
<html>
<body>
<p>%s</p>
</body>
</html>
""" % (message,) '''
***********************************************************************************************************************************************************************
''' Creates the nested frame for the Data pane for the image '''
self._dataPane1 = Frame(self)#, bg = "orange")
self._dataPane1.grid(row = 0, column = 0)
self._pictureImage = PhotoImage(file = "../logo.gif")
self._imageLabel = Label(self._dataPane1, image = self._pictureImage)
self._imageLabel.grid(row = 0, column= 0)
*********************************************************************************************************************************************************************
''' Creates the nested frame for the Data pane'''
self._dataPaneEntryInfo = Frame(self, bg = "white")
self._dataPaneEntryInfo.grid(row = 1, column = 0)
''' Label and field for First Name '''
self._firstNameLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "First Name ")
self._firstNameLabel.grid(row = 0, column = 0)
self._firstNameVar = DoubleVar()
self._firstNameEntry = Entry(self._dataPaneEntryInfo, textvariable = self._firstNameVar)
self._firstNameEntry.grid(row = 0, column = 1)
''' Label and field for Last Name '''
self._LastNameLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Last Name ")
self._LastNameLabel.grid(row = 1, column = 0)
self._LastNameVar = DoubleVar()
self._LastNameEntry = Entry(self._dataPaneEntryInfo, textvariable = self._LastNameVar)
self._LastNameEntry.grid(row = 1, column = 1)
''' Label and field for Phone Number '''
self._phoneNumberLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Phone Number ")
self._phoneNumberLabel.grid(row = 2, column = 0)
self._phoneNumberVar = DoubleVar()
self._phoneNumberEntry = Entry(self._dataPaneEntryInfo, textvariable = self._phoneNumberVar)
self._phoneNumberEntry.grid(row = 2, column = 1)
''' Label and field for Email '''
self._EmailLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Email Address ")
self._EmailLabel.grid(row = 3, column = 0)
self._EmailVar = DoubleVar()
self._EmailEntry = Entry(self._dataPaneEntryInfo, textvariable = self._EmailVar)
self._EmailEntry.grid(row = 3, column = 1)
''' Label and field for Address '''
self._addressLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Address \n (OPITIONAL) ")
self._addressLabel.grid(row = 4, column = 0)
self._addressVar = DoubleVar()
self._addressEntry = Entry(self._dataPaneEntryInfo, textvariable = self._addressVar)
self._addressEntry.grid(row = 4, column = 1)
*********************************************************************************************************************************************************************
''' Label and field for Year of the Car '''
self._yearLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Year ")
self._yearLabel.grid(row = 0, column = 2)
self._yearVar = DoubleVar()
self._yearEntry = Entry(self._dataPaneEntryInfo, textvariable = self._yearVar)
self._yearEntry.grid(row = 0, column = 3)
''' Label and field for Make of the Car '''
self._makeLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Make ")
self._makeLabel.grid(row = 1, column = 2)
self._makeVar = DoubleVar()
self._makeEntry = Entry(self._dataPaneEntryInfo, textvariable = self._makeVar)
self._makeEntry.grid(row = 1, column = 3)
''' Label and field for Model of the Car '''
self._modelLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Model ")
self._modelLabel.grid(row = 2, column = 2)
self._modelVar = DoubleVar()
self._modelEntry = Entry(self._dataPaneEntryInfo, textvariable = self._modelVar)
self._modelEntry.grid(row = 2, column = 3)
''' Label and field for Package of the Car '''
self._packageLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Package ")
self._packageLabel.grid(row = 3, column = 2)
self._packageVar = DoubleVar()
self._packageEntry = Entry(self._dataPaneEntryInfo, textvariable = self._packageVar)
self._packageEntry.grid(row = 3, column = 3)
''' Label and field for VIN # of the Car '''
self._vinLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "VIN # ")
self._vinLabel.grid(row = 4, column = 2)
self._vinVar = DoubleVar()
self._vinEntry = Entry(self._dataPaneEntryInfo, textvariable = self._vinVar)
self._vinEntry.grid(row = 4, column = 3)
******************************************************************************************************************************************************************************************************
''' Creates the nested frame for the Data pane'''
self._dataPaneComment = Frame(self, bg = "black")
self._dataPaneComment.grid(row = 2, column = 0)
'''# Label and info field for Comment Box .'''
self._text = "Enter text here. "
self._outputArea = Text(self._dataPaneComment, width = 50, height = 10, wrap = WORD)
self._outputArea.grid(row = 0, column = 0, columnspan = 2)
*********************************************************************************************************************************************************************************************************
''' Creates the nested frame for the Button pane for the Submit'''
self._buttonPane = Frame(self) #this creates a box for the buttons to be placed in one area.
self._buttonPane.grid(row = 3, column = 0)#this gives the button pane a position in the GUI
''' Black and White button '''
self._button1 = Button(self._buttonPane, text = "SUBMIT", command = self._NameEntry)#This creates the button.
self._button1.grid(row = 0, column = 0) #This gives the button a position in the GUI.
********************************************************************************************************************************************************************************************************
def _NameEntry(self):
open("Results.txt", "w").close()
first = self._firstNameEntry.get()
last = self._LastNameEntry.get()
phone = self._phoneNumberEntry.get()
email = self._EmailEntry.get()
address = self._addressEntry.get()
year = self._yearEntry.get()
make = self._makeEntry.get()
model = self._modelEntry.get()
package = self._packageEntry.get()
vin = self._vinEntry.get()
with open("../" + first + " " + last + ".txt", "a") as the_file:
the_file.write("First Name: " + first + "\n" "Last Name: " + last + "\n" "Phone Number: " + phone + "\n" "Email: " + email + "\n"
"Address: " + address + "\n" "Year: " + year + "\n" "Make: " + make + "\n" "Model: " + model + "\n"
"Package: " + package + "\n" "Vin: " + vin + "\n")
'''open("Results.txt", "w").close()
last = self._LastNameEntry.get()
with open("../Results.txt", "a") as the_file:
the_file.write("Last Name: " + last)'''
'''first = self._firstNameEntry.get()
name = open("Results.txt", "w")
name.write("First Name: ".insert(first))
name.close()'''
def main():
'''Instantiate and pop up the window.'''
App().mainloop()
if __name__ == '__main__':
main()
I'm exactly sure on how to upload the gif file with this code.
The error message is telling you what's wrong. If you have already used one geometry manager within a widget you cannot use another.
e.g. - You cannot use both pack and grid within a frame. You must use one or the other.
You could make another widget and then use the seperate geometry manager within this widget but you would have to use the original manager to place it within the master widget.
Related
I'm attempting to create a GUI for astrophotography, and am trying to add a function that would allow choosing a specific directory for files. I'm using a button with a command, and am trying to run the function (that has an argument) using the lambda function. However, trying to run it I was given a TypeError: uploadFlats() missing 1 required positional argument: 'x'.
class Astrophotography:
def __init__(self):
self.mainWin = tk.Tk()
self.mainWin.title("Automatic Image Editor")
self.firstFrame = tk.Frame(self.mainWin, width = 600, height = 200)
self.secondFrame = tk.Frame(self.mainWin)
self.thirdFrame = tk.Frame(self.mainWin)
# First Frame
self.description = tk.Label(self.firstFrame, text = "Please select a save directory and also directories\
for flats, biases, and darks to create masters of each")
self.flatsLabel = tk.Label(self.firstFrame, text = "Please enter flats directory: ")
self.flatsText = tk.StringVar(value = "")
self.flatsEntry = tk.Entry(self.firstFrame, width = 50, textvariable = self.flatsText)
self.browseflats = tk.Button(self.firstFrame, text = "Browse",
command = lambda: self.uploadFlats(self.flatsText))
self.flatsLabel = tk.Label(self.firstFrame, text = "Please enter flats directory: ")
self.flatsText = tk.StringVar()
self.flatsEntry = tk.Entry(self.firstFrame, width = 50, textvariable = self.flatsText)
self.browseflats = tk.Button(self.firstFrame, text = "Browse", command = self.uploadFlats)
self.darksLabel = tk.Label(self.firstFrame, text = "Please enter darks directory: ")
self.darksText = tk.StringVar()
self.darksEntry = tk.Entry(self.firstFrame, width = 50, textvariable = self.darksText)
self.browsedarks = tk.Button(self.firstFrame, text = "Browse", command = self.uploadDarks)
self.biasLabel = tk.Label(self.firstFrame, text = "Please enter bias directory: ")
self.biasText = tk.StringVar()
self.biasEntry = tk.Entry(self.firstFrame, width = 50, textvariable = self.biasText)
self.browsebias = tk.Button(self.firstFrame, text = "Browse", command = self.uploadBias)
self.enterButton = tk.Button(self.firstFrame, text = "Create Masters", command = self.mastercalibrations)
#-----------------------------------------------------------------------------------------------------------------------
# Placement
self.firstFrame.pack()
self.secondFrame.pack(side = 'left', padx = 5, pady = 5)
self.thirdFrame.pack(side = 'right', padx = 5, pady = 5)
#First Frame
self.initialY = 5
self.spacing = 30
self.description.place(x = 5, y = 5)
self.flatsLabel.place(x = 5, y = self.initialY + self.spacing)
self.flatsEntry.place(x = 200, y = self.initialY + self.spacing)
self.browseflats.place(x = 510, y = self.initialY + self.spacing)
self.darksLabel.place(x = 5, y = self.initialY + 2 * self.spacing)
self.darksEntry.place(x = 200, y = self.initialY + 2 * self.spacing)
self.browsedarks.place(x = 510, y = self.initialY + 2 * self.spacing)
self.biasLabel.place(x = 5, y = self.initialY + 3 * self.spacing)
self.biasEntry.place(x = 200, y = self.initialY + 3 * self.spacing)
self.browsebias.place(x = 510, y = self.initialY + 3 * self.spacing)
self.enterButton.place(x = 5, y = self.initialY + 4 * self.spacing)
self.mainWin.mainloop()
#-----------------------------------------------------------------------------------------------------------------------
def uploadFlats(self, entry):
self.directory = dlg.askdirectory()
#Delete current text in image name entry and replace with found image name
entry.set(0, self.directory)
def uploadDarks(self):
self.directory = dlg.askdirectory()
#Delete current text in image name entry and replace with found image name
self.darksEntry.delete(0, 'end')
self.darksEntry.insert(0, self.directory)
def uploadBias(self):
self.directory = dlg.askdirectory()
#Delete current text in image name entry and replace with found image name
self.biasEntry.delete(0, 'end')
self.biasEntry.insert(0, self.directory)
def mastercalibrations(self):
print('m')
I have tried using lambda functions, the partial function, and have tried seeing if it is just an issue with the my function itself. Regardless of what the uploadFlats actually does, I'm given this same error. I have tried sending in multiple different types of variables, however they are all consistently ignored.
This question already has answers here:
I'm getting a TypeError. How do I fix it?
(2 answers)
TypeError: 'function' object is not subscriptable - Python
(4 answers)
Closed 6 months ago.
I'm working on a tkinter GUI API-based application.
I'm attempting to modularize my code in which each function has a specific task to do and some functions just call other functions.
In my case, I bind the search button to the function, search, whose job is to call other API-based functions, such as full_name.
When I did this, an error is thrown, saying that in search full_name() TypeError: 'Label' object is not callable
what's interesting is that
I see no mention of creating instances of Label classes in full_name()
when I bind the search button to function, full_name(), it works just fine. However, I want to bind it to a function that will call all API-based functions, and so far, it's not working
Here's the code below:
#MER for frames placement through .Grid()
#import necessary modules
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
from tkinter import messagebox
import requests
import json
root = Tk()
root.title("F1 Desktop Application")
root.geometry("500x600")
root.configure(bg="white")
#generate 2022 drivers-list [can scale to drivers-list by changing the]
drivers_list_request = requests.get("http://ergast.com/api/f1/2022/drivers.json")
#initialize empty-list
drivers_list = []
drivers_list_object = json.loads(drivers_list_request.content)
for elements in drivers_list_object["MRData"]["DriverTable"]["Drivers"]:
drivers_list.append(elements["givenName"] + " " + elements["familyName"])
#NEED TO UNDERSTAND PRECEDENCE BETWEEN WIDTH, HEIGHT SETTING, VS SPANS. STICKY MAKES PERFECT SENSE
top_frame = LabelFrame(root, width = 300, height = 125)
top_frame.grid(row = 0, column = 0, columnspan = 2)
top_frame.rowconfigure(0, minsize = 75)
top_frame.columnconfigure(0, minsize = 300)
# Update the Entry widget with the selected item in list
def check(e):
v= entry_box.get()
if v=='':
hide_button(menu)
else:
data=[]
for item in drivers_list:
if v.lower() in item.lower():
data.append(item)
update(data)
show_button(menu)
def update(data):
# Clear the Combobox
menu.delete(0, END)
# Add values to the combobox
for value in data:
menu.insert(END,value)
def fillout(event):
try:
entry_box.delete(0,END)
entry_box.insert(0,menu.get(menu.curselection()))
hide_button(menu)
#handle a complete deletion of entry-box via cursor double tap
except:
pass
def hide_button(widget):
widget.grid_remove()
def show_button(widget):
widget.grid()
def full_name():
user_input = entry_box.get()
lower_user_input = user_input.lower().split(" ")[1]
response = requests.get("http://ergast.com/api/f1/drivers/{}.json".format(lower_user_input))
print(response.status_code)
response_object = json.loads(response.content)
name = response_object["MRData"]["DriverTable"]["Drivers"][0]["givenName"] + " " + response_object["MRData"]["DriverTable"]["Drivers"][0]["familyName"]
print(name)
def search():
full_name()
#once works, then make API request
header_label = Label(top_frame, text = "F1 2022 Drivers App", font = ("Arial bold",14), bg = "white")
header_label.grid(row = 0, column = 0, padx = 30)
search_button = Button(top_frame, text = "search" , command = search)
search_button.grid(row = 1, column = 1)
entry_box= Entry(top_frame)
entry_box.grid(row = 1, column = 0)
entry_box.bind('<KeyRelease>',check)
menu= Listbox(top_frame, height = 4)
menu.grid(row = 2, column = 0)
menu.bind("<<ListboxSelect>>",fillout)
left_frame = LabelFrame(root, width = 250, height = 225, borderwidth = 0, highlightthickness = 2)
left_frame.grid(row = 1, column = 0, sticky = NW, padx = 10, pady = 15)
#left_frame.grid_propagate(False)
left_frame.rowconfigure(0, minsize = 100)
left_frame.columnconfigure(0, minsize = 200)
#left_frame_content = LabelFrame(, width = 125, height = 70)
#left_frame_content.grid(row = 1, column = 1, sticky = W)
basic_info = Label(left_frame, text = "Basic Info ", font = ("Arial bold",14))
basic_info.grid(row = 0, column = 0)
full_name = Label(left_frame, text = "Full Name :")
full_name.grid(row = 1, column = 0, sticky = W)
driver_code = Label(left_frame, text = "Driver Code : ")
driver_code.grid(row = 2, column = 0, sticky = W)
nationality = Label(left_frame, text = "Nationality : ")
nationality.grid(row = 3, column = 0, sticky = W)
bottom_left_frame = LabelFrame(root, width = 250, height = 225)
bottom_left_frame.grid(row = 2, column = 0, sticky = N, padx = 10)
bottom_left_frame.rowconfigure(0, minsize = 50)
bottom_left_frame.columnconfigure(0, minsize = 200)
F1_career = Label(bottom_left_frame, text = "F1 Career ", font = ("Arial bold",14))
F1_career.grid(row = 0, column = 0)
wins = Label(bottom_left_frame, text = "Wins :")
wins.grid(row = 1, column = 0, sticky = W)
wins.configure(text = "Wins :" + " 7")
poles = Label(bottom_left_frame, text = "Poles :")
poles.grid(row = 2, column = 0, sticky = W)
test = Label(bottom_left_frame, text = "test")
test.grid(row = 2, column = 1)
podiums = Label(bottom_left_frame, text = "Podiums :")
podiums.grid(row = 3, column = 0, sticky = W)
podiums.configure(text = "Podiums :" + "Lewis Hamilton")
drivers_championships = Label(bottom_left_frame, text = "Championships :")
drivers_championships.grid(row = 4, column = 0, sticky = W)
bottom_right_frame = LabelFrame(root, width = 250, height = 225)
bottom_right_frame.grid(row = 2, column = 1, sticky = W)
bottom_right_frame.rowconfigure(0, minsize = 50)
bottom_right_frame.columnconfigure(0, minsize = 150)
hide_button(menu)
root.mainloop()
Feel free to ask for more clarity. I would be grateful if anyone has a reason/solution
You have used the same name for a label:
full_name = Label(left_frame, text = "Full Name :")
So it will override the full_name().
Use another name for the label, for example full_name_label:
full_name_label = Label(left_frame, text = "Full Name :")
full_name_label.grid(row = 1, column = 0, sticky = W)
I'm writing a scientific calculator with 2nd button. What is the function for second button so for example it changes sin to sin^-1, plus changing the sin button command; and if you click the 2nd button again, it changes sin^-1 back to sin
I would split my calculator up into section using different frames (one to show the calculations , one with buttons which won't have 2 functions and lastly the buttons which have 2 functions).
The reason I would split it up is because I would use destroying objects and making the new ones this splitting up means you can destroy the wanted frame rather than specific buttons (would require less code). Also for this I would have 3 create GUI defs. one would be the buttons with one function and the bit showing the calculations. one be the buttons which have 2 functions (their first function) and lastly the buttons which have 2 functions (their second functions). To decide between which GUI gen def to use have an if statement with global variable which gets changed each time 2nd function button called and that decides which def to use.
If it was just commands you wanted changing instead of both labels and commands I would have a variable which is etheir 1 or 2(change when 2nd button clicked) then in your definitions (ones which your buttons call) have an if statement to decide between to do normal action (e.g cos) or 2nd action (e.g cos-1).
Here is code below that uses what i have described in the first paragraph:
from tkinter import *
class Calc(Frame):
def __init__(self, master):
self.modefunction = 1
""" Initialize the frame. """
super(Calc,self).__init__(master)
self.grid()
self.calculations_frm = Frame(self, width=100, height=30)#bg = "red"
self.calculations_frm.grid(row = 0, column = 0, columnspan=2)
self.buttons_frm = Frame(self, width= 50, height=30,)#bg = "green")
self.buttons_frm.grid(row = 1, column = 1)
self.buttons_2_functions_1_frm = Frame(self, width=50, height=30)#bg = "blue")
self.buttons_2_functions_1_frm.grid(row = 1, column = 0)
self.create_GUI()
def create_show_calculations(self):
self.calculation_lbl = Label(self.calculations_frm, text = "will show caluclations here").pack()
def create_buttons(self):
#mc stands for mode change
self.mode_change_btn = Button(self.buttons_frm, text = "mc", command = self.mode_change, height = 1, width = 5)
self.mode_change_btn.grid(row = 0,column = 0)
self.plus_btn = Button(self.buttons_frm, text = "plus", height = 1, width = 5)
self.plus_btn.grid(row = 1,column = 0)
def create_GUI(self):
self.create_show_calculations()
self.create_buttons()
self.create_1_function_gui()
def create_1_function_gui(self):
self.tan_btn = Button(self.buttons_2_functions_1_frm, text = "tan", height = 1, width = 5)
self.tan_btn.grid(row = 0,column = 0)
self.san_btn = Button(self.buttons_2_functions_1_frm, text = "san", height = 1, width = 5)
self.san_btn.grid(row = 0,column = 1)
self.coz_btn = Button(self.buttons_2_functions_1_frm, text = "coz", height = 1, width = 5)
self.coz_btn.grid(row = 1,column = 0)
def create_2_function_gui(self):
self.buttons_2_functions_2_frm = Frame(self, width=50, height=30)#bg = "blue")
self.buttons_2_functions_2_frm.grid(row = 1, column = 0)
self.inverse_tan_btn = Button(self.buttons_2_functions_2_frm, text = "tan-1", height = 1, width = 5)
self.inverse_tan_btn.grid(row = 0,column = 0)
self.inverse_san_btn = Button(self.buttons_2_functions_2_frm, text = "san-1", height = 1, width = 5)
self.inverse_san_btn.grid(row = 0,column = 1)
self.inverse_coz_btn = Button(self.buttons_2_functions_2_frm, text = "coz-1", height = 1, width = 5)
self.inverse_coz_btn.grid(row = 1,column = 0)
def mode_change(self):
if self.modefunction == 1:
self.buttons_2_functions_1_frm.destroy()
self.modefunction = 2
self.buttons_2_functions_2_frm = Frame(self, width=50, height=30)#bg = "blue")
self.buttons_2_functions_2_frm.grid(row = 1, column = 0)
self.create_2_function_gui()
else:
self.buttons_2_functions_2_frm.destroy()
self.modefunction = 1
self.buttons_2_functions_1_frm = Frame(self, width=50, height=30)#bg = "blue")
self.buttons_2_functions_1_frm.grid(row = 1, column = 0)
self.create_1_function_gui()
root = Tk()
root.title("booking system")
root.geometry("500x500")
root.configure(bg="white")
app = Calc(root)
root.mainloop()
This is my current code and it displays in a window but literally prints it the way I've typed it (obviously). But is there a way to write these so they are displayed as powers/exponents?
"
questionNum = 0
#SET QUESTIONS HERE
questions = [0,"Given that y = x^4 + 6x^1/2, find dy/dx","Write down the value of 125^1/3","Fully factorise 9x^2 - 25","Find the value of 8^5/3"]
answer1 = [0,"4x^4 + 3x^1/2","25","(3x-5)(3x+5)","1/2"]
answer2 = [0,"4x^3 + 6x^1/2","1/5","(3x+5)(3x+5)","Answer 2 (4)"]
answer3 = [0,"4x^3 + 6x^-1/2","5","(3x-5)(3x-5)","Answer 3 (4)"]
answer4 = [0,"4x^3 + 1/2x^-3/2","125","(9x+5)(x-5)","Answer 4 (4)"]
This is what it looks like:
rightanswers = [0,1,2,3,4] #These are the correct answers
"
This is the bit that needs to be changed. I've added the rest just in case you need any of it to see what's going on:
from tkinter import * #The TKinter module imported in order to create the menus
import sys #Invoke functions and statements - allows operations to work and searches for named modules i.e. TKinter
global questionNum #Connections between functinos and arrays
questionNum = 0
#SET QUESTIONS HERE
questions = [0,"Given that y = x^4 + 6x^1/2, find dy/dx","Write down the value of 125^1/3","Fully factorise 9x^2 - 25","Find the value of 8^5/3"] #This is the question bank which has been set up as an array
answer1 = [0,"4x^4 + 3x^1/2","25","(3x-5)(3x+5)","1/2"] #These are the possible answers - this is where multiple choice answers would go
answer2 = [0,"4x^3 + 6x^1/2","1/5","(3x+5)(3x+5)","Answer 2 (4)"]
answer3 = [0,"4x^3 + 6x^-1/2","5","(3x-5)(3x-5)","Answer 3 (4)"]
answer4 = [0,"4x^3 + 1/2x^-3/2","125","(9x+5)(x-5)","Answer 4 (4)"]
rightanswers = [0,1,2,3,4] #These are the correct answers
normal = Tk() #Build the TKinter
normal.geometry("850x350") #Set the size of the normal chess form to 850x350
normal.title("Normal Chess") #Sets a title for the normal chess form
normal.columnconfigure(1,minsize = 300) #This is whereabouts the question and answers are displayed
questionVar = StringVar() #Question will be a string
answerVar = IntVar() #Answers will be numbers
answerVar.set(1) #Questions can only have one solution
aText = StringVar() #Text for the answers - options
bText = StringVar()
cText = StringVar()
dText = StringVar()
qNoText = StringVar() #Questions text which is displayed to the user
questionText = StringVar()
normal.withdraw() #Allows the user to only select one option
title = Tk() #Builds the TKinter
title.title("Chess") #Title of the form
title.geometry("300x300") #The size of the image
watermark = PhotoImage(file = "watermark.gif") #Link to the image itself
Label(image = watermark).place(x=0,y=0,relwidth=1,relheight=1) #Places the image onto the form set on the x,y coordinates
title.withdraw()
menu = Tk() #Builds the TKinter
menu.title("Main Menu") #Displays 'Main Menu' on screen
menu.geometry("400x350") #Size of the form
p1var = StringVar() #Sets a variable for Player 1 and Player 2
p2var = StringVar()
def Quit(): #Quit function - allows the user to exit the program
menu.destroy()
title.destroy()
normal.destroy()
sys.exit() #Gets rid of all the modules
def play():
title.deiconify()
Label(title,text = "Enter Details:",font = ("Calibri",25)).grid(row = 1, column = 1)
#'Enter Details' font, size and location on the form
Label(title,text = "CHESS",font = ("Calibri",50)).grid(row = 0,column = 1)
#'CHESS' font, size and location on the form
Label(title, text = "Player 1: ").grid(row = 2,column = 0)
#'Player 1' font, size and location on the form
Entry(title,textvariable = p1var,width = 30).grid(row = 2,column = 1)
#Allows the user to input a string for the player 1 name
Label(title, text = "Player 2: ").grid(row = 3,column = 0)
#'Player 2' font, size and location on the form
Entry(title,textvariable = p2var,width = 30).grid(row = 3,column = 1)
#Allows the user to input a string for the player 2 name
Label(title,text = "Select Game Mode: ").grid(row = 4,column = 1)
#'Select Game Mode: ' font, size and location on the form
Button(title,command = lambda: playNormalChess(p1var.get(),p2var.get()),text = "Normal Chess").grid(row = 6,column = 1,sticky = W)
#Button for normal chess
Button(title,command = lambda: playSpeedChess(p1var.get(),p2var.get()),text = "Speed Chess").grid(row = 6,column = 1,sticky = E)
#Button for speed chess
Button(title,command = instructions,text = "Instructions").grid(row = 7,column = 1,pady =10)
#Button for instructions
def playNormalChess(p1,p2):
normal.deiconify()
t = Label(textvariable = qNoText,font = ("Arial",50)).grid(row = 0,column = 1,sticky = W,columnspan=2,padx = 20,pady =10)
#Functions for selection
q =Label(textvariable = questionVar,font = ("Arial",30)).grid(row = 1,column = 1,sticky = W,columnspan=2,padx = 20,pady =10)
#Font and size the questions are set in
a=Radiobutton(variable = answerVar,value = 1,textvariable = aText,font = ("Arial",18)).grid(row = 3,column = 1,pady =5,padx = 20,sticky = W)
#These are the radio buttons which are linked to the answers - set the font and the size of the text
b=Radiobutton(variable = answerVar,value = 2,textvariable = bText,font = ("Arial",18)).grid(row = 4,column = 1,padx = 20,sticky = W)
c=Radiobutton(variable = answerVar,value = 3,textvariable = cText,font = ("Arial",18)).grid(row =5,column = 1,pady = 5,padx = 20,sticky = W)
d=Radiobutton(variable = answerVar,value=4,textvariable = dText,font = ("Arial",18)).grid(row = 6,column = 1,padx = 20,sticky = W)
Button(text = "Submit",command = confirm).grid(row =0,column = 3,sticky = W,pady = 10) #Submit button to confirm their answers
newQuestion() #Calls the function for a new question
def confirm():
if messagebox.askyesno('Confirm','Are You Sure?'): #This is the conformation of the correct answer for the user
try:
if answerVar.get() == rightanswers[questionNum]: #If they select yes to confirm they are happy with the selection
# - it checks their answer with the correct answer and prints 'Right' or 'Wrong' depending on their answer
print("Right")
else:
print("Wrong")
newQuestion() #Once their question is answered, a new question will be presented to them
except IndexError:
print("No more Questions")
def newQuestion():
global questionNum
questionNum = questionNum + 1
try:
qNoText.set("Question "+str(questionNum))
aText.set(answer1[questionNum])
bText.set(answer2[questionNum])
cText.set(answer3[questionNum])
dText.set(answer4[questionNum])
questionVar.set(questions[questionNum])
except IndexError:
print("No more questions")
Label(menu,text = "AS Maths Chess",font = ("Arial",37)).pack(pady = 20)
Button(menu,text = "Play",background = "black",foreground = "white",font = ("Arial",20),command = play).pack(ipadx = 80,ipady = 20, pady = 10)
Button(menu,text = "Quit",font = ("Arial",20),command = Quit).pack(ipadx = 80,ipady = 20, pady = 10)
Unicode has superscript numerals, arithmetic operators, and some letters in the BMP, which is supported by tcl/tk. See Wikipedia. Within those constraints, and given a supporting font, the answer is yes. On Windows, running from IDLE, the following works nicely and looks nice, though I would want the tk font larger to see the superscript easily with my eyes.
import tkinter as tk
root = tk.Tk()
# "4x^4 + 3x^1/2"
t1 = "4x\u2074 + 3x\u207b\u00b2" # \u excapes, if needed
t2 = "4x⁴ + 3x⁻²"
label = tk.Label(root, text=t2)
label.pack()
The following things I want is to add multiple different tasks, and there is a task start button which is used to trig a timer.
class Pomodoro_app(Tk):
def add_task(self):
global time
time = StringVar()
time.set("Start")
task_content = askstring(title = 'Add a Task', prompt = "Input a task")
task_label = Label(self, text = task_content, font = ("Arial, 12")).grid(column = 0, row = 3)
task_start_button = Button(self, textvariable = time, command = self.start_working).grid(column = 1, row = 3)
def createWidgets(self):
self.welcome_label = Label(self, text = "Welcome to the Challenge!", font = ("Arial, 12")).grid(column = 0, row = 0, columnspan = 2)
self.add_task_button = Button(self, text = "Add Task", width = 20, command = self.add_task).grid(column = 0 , columnspan = 2)
def __init__(self):
"""GUI Initiation"""
Tk.__init__(self)
self.createWidgets()
"""window Initiation"""
self.resizable(False, False)
x = (self.winfo_screenwidth() - self.winfo_reqwidth()) / 2
y = (self.winfo_screenheight() - self.winfo_reqheight()) / 2
self.geometry('250x400+%d+%d' % (x, y))
Using lambda (or inner function), you can pass additional argument to callback.
For example:
class Pomodoro_app(Tk):
def add_task(self):
global time
time = StringVar()
time.set("Start")
task_content = askstring(title = 'Add a Task', prompt = "Input a task")
task_label = Label(self, text = task_content, font = ("Arial, 12")).grid(column = 0, row = self.next_row)
task_start_button = Button(self, textvariable = time, command = lambda: self.start_working(task_content)).grid(column = 1, row = self.next_row)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
self.next_row += 1
def start_working(self, task_name):
print('start working', task_name)
def createWidgets(self):
self.welcome_label = Label(self, text = "Welcome to the Challenge!", font = ("Arial, 12")).grid(column = 0, row = 0, columnspan = 2)
self.add_task_button = Button(self, text = "Add Task", width = 20, command = self.add_task).grid(column = 0 , columnspan = 2)
def __init__(self):
"""GUI Initiation"""
Tk.__init__(self)
self.createWidgets()
"""window Initiation"""
self.resizable(False, False)
x = (self.winfo_screenwidth() - self.winfo_reqwidth()) / 2
y = (self.winfo_screenheight() - self.winfo_reqheight()) / 2
self.geometry('250x400+%d+%d' % (x, y))
self.next_row = 3