Is there a way to write superscripts in python in a GUI? - python

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()

Related

Why is my Tkinter button command ignoring the arguments I'm sending into a function?

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.

The tkinter entry widget get function in attend is not returning anything

I am trying to make an attendance app for my lecture. Here I got stuck when dealing with tkinter widget.
from functools import partial
from tkinter import *
from tkinter import messagebox
from tkcalendar import Calendar, DateEntry
# def focus_course(event):
# course_name.focus_set()
# def focus_topic(event):
# topic_name.focus_set()
# def focus_studN(event):
# student_name.focus_set()
ca=StringVar
ta=StringVar
sname=StringVar
**
def attend(courseN,topicN,studN):
ca=(courseN.get())
ta=(topicN.get())
sname=(studN.get())
if((ca != "") or (ta != "") or (sname != "")):
messagebox.showinfo("success", "all fields save")
print("hello")
else:
print("printing")
messagebox.showinfo("error", "please enter all fields")
**
if __name__=="__main__":
# global submit_button
# global course_name
# global topic_name
# global student_name
top = Tk()
top.geometry("450x300")
# the label for user_name
# the label for user_password
dlabel = Label(top,
text = "Date").place(x = 40,
y = 22)
dlabel = Label(top,
text = "Course").place(x = 40,
y = 60)
topic = Label(top,
text = "Topic").place(x = 40,
y = 100)
students = Label(top,
text = "Students present").place(x = 40,
y = 140)
courseN=StringVar()
topicN=StringVar()
studN=StringVar()
date = DateEntry(top, width= 16, background= "magenta3", foreground= "white",bd=2)
course_name = Entry(top,width = 30,textvariable="courseN").place(x = 150,
y = 60)
topic_name = Entry(top,width = 30,textvariable="topicN").place(x = 150,
y = 100)
student_name = Entry(top,width= 30,textvariable="studN").place(x=150,y=140)
attend=partial(attend,courseN,topicN,studN)
submit_button = Button(top,
text = "Submit",command=attend).place(x = 120,
y = 180)
print(type(course_name))
# course_name.bind("<Return>", focus_course)
# topic_name.bind("<Return>", focus_topic)
# student_name.bind("<Return>", focus_studN)
date.pack(pady=20)
top.mainloop()
# startapp()
Here I tried lot of things but never succeed in one. What can I try next?

How to change color of a special frame in Tkinter TTK? [duplicate]

This question already has answers here:
Setting background color of a tkinter ttk frame
(3 answers)
Closed 3 years ago.
I want to change the background of my ttk form (ceasar code script) to the color I have in my window = #FEFB22
I want to change the white "box" color to #FEFB22 click to see image !
from tkinter import *
from tkinter import ttk
# variables
letters="ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
# fenetre
root = Tk()
#window title
root.title('Cesar Crypt/Decrypt par Maxence')
root.iconbitmap("logo.ico")
# allows for window to be resized
root.geometry("850x480")
# window background
root.configure(background='#FEFB22')
root.frame_header = ttk.Frame()
ttk.Label(root.frame_header, text = 'Code César', style = 'Header.TLabel').grid(row = 0, column = 1)
ttk.Label(root.frame_header, text = 'Entrez un nombre entre 1 et 25 :', style = 'Header.TLabel').grid(row = 1, column = 0)
ttk.Label(root.frame_header, text = 'Votre Message:', style = 'Header.TLabel').grid(row = 2, column = 0)
ttk.Label(root.frame_header, text='Votre message crypté/decrypté:',style='Header.TLabel').grid(row=4, column=0)
enc_dec_text = ttk.Entry(root.frame_header, width=110)
enc_dec_text.grid(row=4,column=1)
cipher_shift_menu = StringVar()
Spinbox(root.frame_header,from_=1, to=25, textvariable=cipher_shift_menu).grid(row=1, column=1)
text_entry = ttk.Entry(root.frame_header, width=100)
text_entry.grid(row=2,column=1)
def encrypt_text():
stringtoencrypt = text_entry.get()
stringtoencrypt = str(stringtoencrypt)
stringtoencrypt=stringtoencrypt.upper()
ciphershift = cipher_shift_menu.get()
ciphershift=int(ciphershift)
stringencrypted=""
for character in stringtoencrypt:
position = letters.find(character)
newposition = position+ciphershift
if character in letters:
stringencrypted = stringencrypted + letters[newposition]
else:
stringencrypted = stringencrypted + character
enc_dec_text.insert(0, stringencrypted)
def decrypt_text():
stringtodecrypt = text_entry.get()
stringtodecrypt = str(stringtodecrypt)
stringtodecrypt=stringtodecrypt.upper()
ciphershift = cipher_shift_menu.get()
ciphershift=int(ciphershift)
stringdecrypted=""
for character in stringtodecrypt:
position = letters.find(character)
newposition = position-ciphershift
if character in letters:
stringdecrypted = stringdecrypted + letters[newposition]
else:
stringdecrypted = stringdecrypted + character
enc_dec_text.insert(0, stringdecrypted)
#add image
width = 200
lenght = 200
image = PhotoImage(file="logort.png")
#bouton image
button = Button(root, image=image, bg='#FEFB22', bd=0, relief=SUNKEN)
button.pack()
# boutous
encrypt_button = ttk.Button(root.frame_header,text='Encrypter',command = lambda: encrypt_text()).grid(row=3,column=0)
decrypt_button = ttk.Button(root.frame_header,text='Decrypter',command = lambda: decrypt_text()).grid(row=3,column=1)
#bouton q
# uitter
bouton_quitter = Button(root, text="Quitter !", command=root.quit, font=("Courrier", 20), bg='#000000', fg='#FEFB22')
bouton_quitter.pack(side=BOTTOM)
root.frame_header.pack()
root.mainloop()
You can use ttk.Style to change the frame background color:
s = ttk.Style()
s.configure('My.TFrame', background='#FEFB22')
root.frame_header = ttk.Frame(root, style='My.TFrame')

Python Status Bar

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.

How do I validate an entry widget in python?

I'm creating a GUI using Tkinter that is used to collect information from a user. I need to validate:
First and Last name only contain letters, apostrophes, and dashes
Address
Phone number has the correct number of digits
Valid birthday (Feb 31 doesn't exist and birth year between 1900 and 2014)
Email address contains '#' and '.'
Here is my code:
from tkinter import *
import datetime
class tkwindow:
def __init__(self):
window = Tk() # Create window
window.title("Contact Form") # Give window a title
menubar = Menu(window) # Create menu bar
window.config(menu = menubar) # Display menu bar
'''Using the pulldown menu allows easier access to the menu items instead of using a pop-up menu '''
# Create pulldown menu and add to menu bar
messagesMenu = Menu(menubar, tearoff = 0)
menubar.add_cascade(label = "Messages", menu = messagesMenu)
messagesMenu.add_command(label = "Send a Birthday Greeting", command = self.bdayGreeting)
messagesMenu.add_command(label = "Print Address", command = self.printAddress)
# Create another menu option
endMenu = Menu(menubar, tearoff = 0)
menubar.add_cascade(label = "End", menu = endMenu)
endMenu.add_command(label = "Reset Form", command = self.resetForm)
endMenu.add_command(label = "Exit Program", command = window.quit)
# Using Label widget
labelFirst = Label(window, text = "First Name: ").grid(row = 1, column = 1, sticky = E)
labelLast = Label(window, text = "Last Name: ").grid(row = 2, column = 1, sticky = E)
labelAddress = Label(window, text = "Address: ").grid(row = 3, column = 1, sticky = E)
labelPhone = Label(window, text = "Phone Number (8005551234): ").grid(row = 4, column = 1, sticky = E)
labelBday = Label(window, text = "Birthday (MM/DD/YYYY): ").grid(row = 5, column = 1, sticky = E)
labelEmail = Label(window, text = "Email Address (user#domain.com): ").grid(row = 6, column = 1, sticky = E)
# Using Entry widget
self.firstName = StringVar()
entryFirst = Entry(window, textvariable = self.firstName, justify = LEFT).grid(row = 1, column = 2, sticky = W)
self.lastName = StringVar()
entryLast = Entry(window, textvariable = self.lastName, justify = LEFT).grid(row = 2, column = 2, sticky = W)
self.address = StringVar()
entryAddress = Entry(window, textvariable = self.address, justify = LEFT).grid(row = 3, column = 2, sticky = W)
self.phone = StringVar()
entryPhone = Entry(window, textvariable = self.phone, justify = LEFT).grid(row = 4, column = 2, sticky = W)
self.bday = StringVar()
entryBday = Entry(window, textvariable = self.bday, justify = LEFT).grid(row = 5, column = 2, sticky = W)
self.email = StringVar()
entryEmail = Entry(window, textvariable = self.email, justify = LEFT).grid(row = 6, column = 2, sticky = W)
self.errorLblFirst = Label(window, fg = "red")
self.errorLblFirst.grid(row = 1, column = 3)
self.errorLblLast = Label(window, fg = "red")
self.errorLblLast.grid(row = 2, column = 3)
self.errorLblAddress = Label(window, fg = "red")
self.errorLblAddress.grid(row = 3, column = 3)
self.errorLblPhone = Label(window, fg = "red")
self.errorLblPhone.grid(row = 4, column = 3)
self.errorLblBday = Label(window, fg = "red")
self.errorLblBday.grid(row = 5, column = 3)
self.errorLblEmail = Label(window, fg = "red")
self.errorLblEmail.grid(row = 6, column = 3)
# Using Button widget
buttonSubmit = Button(window, text = "Submit", command = self.submit).grid(row = 7, column = 2, sticky = E)
window.mainloop()
def resetForm(self):
self.firstName.set('')
self.errorLblFirst["text"] = ''
self.lastName.set('')
self.errorLblLast["text"] = ''
self.address.set('')
self.errorLblAddress["text"] = ''
self.phone.set('')
self.errorLblPhone["text"] = ''
self.bday.set('')
self.errorLblBday["text"] = ''
self.email.set('')
self.errorLblEmail["text"] = ''
def validFirst(self):
for letter in self.firstName.get():
if not letter.isalpha() and letter not in "'-":
self.errorLblFirst["text"] = " * Letters, apostrophes('), and hypens(-) only"
return False
return True
def validLast(self):
for letter in self.lastName.get():
if not letter.isalpha() and letter not in "'-":
self.errorLblLast["text"] = " * Letters, apostrophes('), and hypens(-) only"
return False
return True
def validAddress(self):
for letter in self.address.get():
if not letter.isalnum() and letter not in "'- .,":
self.errorLblAddress["text"] = " * No special characters"
return False
return True
def validPhone(self):
D = 0
for number in self.phone.get():
if number.isdigit():
D += 1
if D == 10:
return True
else:
self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
return False
return True
def validBday(self):
'''try:
valid_date = datetime.datetime.strptime(str(self.bday), '%m/%d/%Y')
except ValueError:
print('Invalid date!')'''
return True
def validEmail(self):
for letter in self.email.get():
if not letter.isalnum() and letter not in "#.":
self.errorLblEmail["text"] = " * Must have # and ."
return False
return True
def bdayGreeting(self):
if self.validBday() and self.validFirst() == True:
print("Happy Birthday" + self.firstName.get() + "\n" + self.bday.get())
def printAddress(self):
if self.validFirst() and self.validLast() and self.validAddress() == True:
print(self.firstName.get() + " " + self.lastName.get() + "\n" + self.address.get())
def submit(self):
self.validFirst()
self.validLast()
self.validAddress()
self.validPhone()
self.validBday()
self.validEmail()
tkwindow()
I have a couple questions.
Starting from def validFirst(self), how do I validate the different entry fields? I keep getting NameError: name "asdf" is not defined, SyntaxError: unexpected EOF while parsing, and TypeError: 'int' object is not subscriptable when I modify the code and I'm still stuck on validFirst(self).
I have a set of labels in column 3 reserved for error messages: errorLblFirst = Label(window, text = " ", fg = "red").grid(row = 1, column = 3). Is it possible to set it to " * Invalid Entry", fg = "red" when the validation for that entry fails? Is there another way to get error messages to show?
Thanks in advance for the input!
Edit: I updated to my latest code. Most of the validation works now except for validBday and validEmail if you could check it out.
errorLblFirst = Label(...).grid(...)
This way you assign result of grid() to errorLblFirst but grid() always returns None
Always do it this way
errorLblFirst = Label(...)
errorLblFirst.grid(...)
And now you can do (for example)
errorLblFirst["text"] = " * Invalid Entry"
errorLblFirst["fg"] = "red"
EDIT:
You forgot len() in for i in range(first): in validFirst()
And you don't need eval().
(You got the same problem in validPhone())
F = 0
fName = True
first = self.firstName.get() # without eval()
for i in range(len(first)): # len()
if first[i].isdigit():
F += 1
if F > 0:
return False
else:
return fName
return fName
but you could do this shorter
for letter in self.firstName.get():
if letter.isdigit():
return False
return True
if you need only letters (no space, commas, etc.) you could do this
return self.firstName.get().isalpha()
EDIT:
I see First Name can have apostrophes, and dashes
for letter in self.firstName.get():
if not letter.isalpha() and letter not in "'-":
return False
return True
EDIT: problem with self.phone and StringVar
self.phone is StringVar() - not string
but StringVar() has .get() to get string
for number in range(len( self.phone.get() )):
By the way: you can do for loop more pythonic - without range(len())
for char in self.phone.get():
if char.isdigit():
EDIT: problem with validEmail() and validBday()
Email validation needs more if.
For example you could add
email = self.email.get()
if '#' not in email and '.' not in email::
print( 'email needs # and . at the same time')
but '.#' will pass this test :/
Real email validation is more complicated.
See valid email examples: https://fightingforalostcause.net/content/misc/2006/compare-email-regex.php
self.bday is StringVar - use self.bday.get() in place of str(self.bday)
EDIT:
def validPhone(self):
D = 0
for number in self.phone.get():
if number.isdigit():
D += 1
# outside
if D == 10:
return True
else:
self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
return False
return True
or even
def validPhone(self):
# remove previous error message
self.errorLblPhone["text"] = ""
D = 0
for number in self.phone.get():
if number.isdigit():
D += 1
if D != 10:
self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
return False
return True
If number can have only 10 digits (no space, no - , etc):
def validPhone(self):
# remove previous error message
self.errorLblPhone["text"] = ""
D = True
for number in self.phone.get():
if not number.isdigit():
D = False
break
if not D or len(number) != 10:
self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
return False
return True

Categories

Resources