manipulating entry box data - python

I am trying to make a quiz game. However when I try to make an entry box and manipulate the data it throws an error. What I need is an explanation to how i can properly structure an entry widget and be able to store the inputted data to a variable. Here is the code:
while True:
random_question = random.randint(0, 39)
if questions_asked == 20:
end_label = tkinter.Label(self, "Your score for that round was {} . For another look at your scores go to the scores page".format(score))
end_label.pack()
break
question_label = tkinter.Label(self , text="{}".format(questions[random_question]))
user_entry = tkinter.Entry(self, "Type your answer here : ")
user_entry.pack()
stored_entry = user_entry.get()
remove_key(random_question)
if stored_entry == "end":
end_label = tkinter.Label(self, "Your score for that round was {} . For another look at your scores go to the scores page".format(score))
end_label.pack()
break
else:
verify(stored_entry)
continue
home_button = ttk.Button(self, text="Go back to home page", command=lambda: shown_frame.show_frame(OpeningFrame))
home_button.pack(pady=10, padx=10)
Here is the error:
File "app.py", line 132, in <module>
app = MyQuiz()
File "app.py", line 21, in __init__
frame = f(main_frame, self)
File "app.py", line 117, in __init__
user_entry = tkinter.Entry(self, "Type your answer here : ")
File "/usr/lib/python3.5/tkinter/__init__.py", line 2519, in __init__
Widget.__init__(self, master, 'entry', cnf, kw)
File "/usr/lib/python3.5/tkinter/__init__.py", line 2138, in __init__
classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)]
AttributeError: 'str' object has no attribute 'items'

Your error is at this line:
user_entry = tkinter.Entry(self, "Type your answer here : ")
because Entry expects only keyword arguments apart from the parent window. So you should replace this line by:
user_entry = tkinter.Entry(self)
user_entry.insert(0, "Type your answer here : ")
Remark: Unlike labels or buttons, entry widgets don't have a text keyword to set the initial text. It has to be set after, using the insert method.

Related

My search in python using tree view is not working/displaying the search results

This is my two functions which operate my search. The problem seems to occur with my search function when I binded it to my key releases on my search entries. However when I search with my button it works with no error messages .
def SearchCustomer(self):
connection = sqlite3.connect("Guestrecord.db")
cursor = connection.cursor()
columnID = ["title","firstName","surname","dob","payment","email","address","postcode"]
columnStr =["Title","FirstName","Surname","DOB","Payment","Email","Address","Postcode"]
self.search_table = ttk.Treeview(self.search_frame,columns=columnID,show="headings")
self.search_table.bind("<Motion>","break")
for i in range(0,8):
self.search_table.heading(columnID[i],text = columnStr[i])
self.search_table.column(columnID[i],minwidth = 0, width = 108)
self.search_table.place(x=20,y=0)
for GuestRec in cursor.execute("SELECT * FROM tb1Guest1"):
self.search_table.insert("",END,values=GuestRec)
connection.commit()
connection.close()
SearchCustomer(self)
search_icon = Image.open("search icon.png")
search_icon_resize = search_icon.resize((20,20))
search_icon = search_icon_resize
search_icon_photo = ImageTk.PhotoImage(search_icon)
self.search_firstname = Entry(self.search_frame2, width=30,bg="#e2f0d9",font=("Avenir Next",18),highlightthickness = 0,relief=FLAT)
self.search_firstname.place(x = 140, y =0)
self.search_firstname_label = Label(self.search_frame2,bg = "white", text = "First Name", font=("Avenir Next",20))
self.search_firstname_label.place(x= 20,y=0)
self.search_Surname = Entry(self.search_frame2, width=30,bg="#e2f0d9",font=("Avenir Next",18),highlightthickness = 0,relief=FLAT)
self.search_Surname.place(x = 140, y =40)
self.search_Surname_label = Label(self.search_frame2,bg = "white", text = "Surname", font=("Avenir Next",20))
self.search_Surname_label.place(x= 20,y=40)
searchButton = Button(self.search_frame2, image=search_icon_photo,height = 35, width =35, command=self.Search,bg ="white")
searchButton.place(x= 500, y = 0)
## Binding entries
self.search_firstname.bind("<KeyRelease>",self.Search)
self.search_Surname.bind("<KeyRelease>",self.Search)
def Search(self):
sFirst_Name = self.search_firstname.get()
sSurname = self.search_Surname.get()
search_rec = (sFirst_Name,sSurname)
search_rec_new = tuple(item for item in search_rec if item !="")
search_fields = ["guestFirstname","guestFirstname"]
search_SQL = "SELECT * FROM tb1Guest1 WHERE guestID LIKE '%'"
for i in range(len(search_rec)):
if search_rec[i] != "":
search_SQL += " AND " + search_fields[i] + " LIKE '%' || ? || '%'"
connection = sqlite3.connect("Guestrecord.db")
cursor = connection.cursor()
# Clearing search results
for rec in self.search_table.get_children():
self.search_table.delete(rec)
#Display the records
for GuestRec in cursor.execute(search_SQL,search_rec_new):
self.search_table.insert("",END,values=GuestRec)
connection.commit()
connection.close()
Then this is the message which pops up when I try to type in my search entries:
It may have something to do with my .self but I don't know how I would over come this error
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/tkinter/__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
TypeError: Main_menu.Search() takes 1 positional argument but 2 were given
If someone could provide a solution to my problem it would be great as I have spend seemingly a lot of time trying to figure this error out.
The function for a binding event expects an argument: the Event object. However you also use the same function for a button command which does not expect that extra argument.
So you need to add an optional argument to Search():
# event argument is optional, if not provided, it will be None
def Search(self, event=None):
...

_tkinter.TclError: wrong # args: should be ".!entry4 insert index text"

I'm trying to list all the data i got from my database using tkinter.
I'm following this post: https://www.geeksforgeeks.org/create-table-using-tkinter/
I got this erorr:
File "/Users/nobu/WorkSpace/Python/CommandLineApps/guineapig/guineapig/gui_tkinter.py", line 18, in __init__
self.entry.insert(END, result[i][j])
File "/usr/local/Cellar/python#3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/__init__.py", line 3056, in insert
self.tk.call(self._w, 'insert', index, string)
_tkinter.TclError: wrong # args: should be ".!entry4 insert index text"
Here's my code:
from tkinter import *
import mysql.connector
import utils
class Table:
def __init__(self,root, result):
# code for creating table
total_rows = len(result)
total_columns = len(result[0])
for i in range(total_rows):
for j in range(total_columns):
self.e = Entry(root, width=20, fg='white')
self.e.grid(row=i, column=j)
self.e.insert(END, result[i][j]) # <- Here I got an error
def get_all():
connection, cursor = utils.connect_db()
with connection:
root = Tk()
cursor.execute("SELECT * FROM item ORDER BY item_id DESC")
result = cursor.fetchall()
if len(result) == 0:
label = Label(text="There are no items. Please create one.")
else:
table = Table(root, result)
root.mainloop()
I'm very new to tkinter. Please help me solve this issue.
Thank you #Bryan Oakley!
My list has None, so I did this:
if result[i][j] is not None:
self.entry.insert(END, result[i][j])
else:
self.entry.insert(END, "None")

How can I create a table in a DOCX file with Python?

I am trying to send selected values from radiobuttons into a .docx file
importing what I need, focus is on docx
import tkinter as tk
from docx import Document
main = tk.Tk()
these are my options that I need to place into a word document on the left of the table, they act as questions in a survey.
info = ["option 1", "option 2", "option 3", "option 4"
]
Here I am placing radiobuttons called Yes, No & N/A which are answers to the options on the left(list of info above) and also Label to represent options or in other words questions..
vars = []
for idx,i in enumerate(info):
var = tk.IntVar(value=0)
vars.append(var)
lblOption = tk.Label(main,text=i)
btnYes = tk.Radiobutton(main, text="Yes", variable=var, value=2)
btnNo = tk.Radiobutton(main, text="No", variable=var, value=1)
btnNa = tk.Radiobutton(main, text="N/A", variable=var,value=0)
lblOption.grid(column=0,row=idx)
btnYes.grid(column=1,row=idx)
btnNo.grid(column=2,row=idx)
btnNa.grid(column=3,row=idx)
Here is my function, creating a document and saving is the easy part. My issue is that I am muddled up creating a table that will have; Options on the left (from info) at the top are the headers (see RadioButtons yes, no, & N/a). And selected data, as an example, if for option 1 I have selected No, then save the data into a .docx file with the one been selected (See example bottom of page at Desired output).
def send():
document = Document()
section = document.sections[0]
#add table
table = document.add_table(1, 4)
#style table
table.style = 'Table Grid'
#table data retrived from Radiobuttons
items = vars.get()
#populate header row
heading_cells = table.rows[0].cells
heading_cells[0].text = "Options"
heading_cells[1].text = btnYes.cget("text")
heading_cells[2].text = btnNo.cget("text")
heading_cells[3].text = btnNa.cget("text")
for item in items:
cells = table.add_row().cells
cells[0].text = #Options
cells[1].text = #Yes values
cells[2].text = #No values
cells[3].text = #N/A values
#save doc
document.save("test.docx")
#button to send data to docx file
btn = tk.Button(main, text="Send to File", command= send)
btn.grid()
main.mainloop()
this is what it opens up:
Here is the desired output:
Number 1 represents selected items from the tkinter application. But will figure out how to change it to a tick box.
I am kinda confused where I am at, I am new using docx.. been trying to read the documentation.. and this is where I digged my self a hole into.
In your current code, vars is a list of IntVars. You want to get each value individually instead of vars.get(). Also when writing to docx file, you need both info and values of radiobuttons, to track them both you can use an index.
With minimal changes to your code, you can use something like this.
def send():
...
...
heading_cells[3].text = btnNa.cget("text")
for idx, item in enumerate(vars):
cells = table.add_row().cells
cells[0].text = info[idx] # gets the option name
val = item.get() #radiobutton value
if val == 2: # checks if yes
cells[1].text = "1"
elif val == 1: # checks if no
cells[2].text = "1"
elif val == 0: # checks if N/A
cells[3].text = "1"
#save doc
document.save("test.docx")
or you can use a dictionary to map radiobuttons to cells.
valuesCells = {0: 3, 1: 2, 2: 1} # value of radiobutton: cell to write
# hard to read what's going on though
for idx, item in enumerate(vars):
cells = table.add_row().cells
cells[0].text = info[idx] # gets the option name
val = item.get()
cells[valuesCells[val]].text = "1"
#save doc
document.save("test.docx")

Python Entry Button Submit issues

Currently with the below code I seem to be getting a weird issue as well cant seem to get the value of refreshtoken when I click the submit button. I do get the print for word but for refreshtoken I receive .!entry in the Console.
def getCommand(r):
print('word')
print(r)
tokenWindowFrame = Tk()
tokenWindowFrame.title("Add Character")
refreshLabel = ttk.Label(tokenWindowFrame, text="Refresh Token : ")
refreshLabel.grid(row=1,column=1)
refreshToken = ttk.Entry(tokenWindowFrame, width = 50)
refreshToken.grid(row=1,column=2)
button = ttk.Button(tokenWindowFrame, text = "Submit", command=lambda
r=refreshToken: getCommand(r))
button.grid(row=3,column=2)
tokenWindowFrame.mainloop()
You can't print an entry object, you need to print the text in the entry object. Use:
refreshToken.get()
I ended up having to change this line
button = ttk.Button(tokenWindowFrame, text = "Submit", command=lambda r=refreshToken: getCommand(r))
To :
button = ttk.Button(tokenWindowFrame, text = "Submit", command=lambda r=refreshToken: getCommand(r.get()))
The r.get() is what I was missing. As both print(r.get()) would not work in the Function.
To get the text in an entry box you need:
<entry_box>.get()
If you are trying to print it then you could just do:
print(<entry_box>.get())
Or in your case:
print(r.get())
Hope this works for you!

Open XML file in Python and add user input

I am creating a program with python 2.7, using Tkinter as the GUI, and elementtree, where the data entered by the user is stored in an XML file. I have managed to create the XML file using python and this saves to the file 'crimeFile.xml', with all empty tags. The GUI also displays the fields and text boxes that allow the user to enter in text. The problem is that when I try and save an entry, I get an error, and the data is not saved to the XML file.
from xml.etree import ElementTree
from xml.etree.ElementTree import Element
from xml.etree.ElementTree import SubElement
import xml.etree.ElementTree as ET
from Tkinter import *
class Application(Frame):
def create_XML(self):
crimeReport = Element('crime report')
caseNo = SubElement(crimeReport, 'case number')
victimDetails = SubElement(caseNo, 'victim details')
victimFirstName = SubElement(victimDetails, 'victims first name')
victimSecondName = SubElement(victimDetails, 'victim surname')
victimAddress = SubElement(victimDetails, 'victim address')
output_file = open('crimeFile.xml', 'w')
output_file.write('<?xml version="1.0"?>')
output_file.write(ElementTree.tostring(crimeReport))
output_file.close()
def save_XML(self):
record = ET.SubElement(self.crimeReport, 'crime report')
caseNoNode = ET.SubElement(record, 'case number')
caseNoNode.text = self.caseNo.get()
victimFirstNameNode = ET.SubElement(record, 'first name')
victimFirstNameNode.text = self.victimFirstName.get()
victimSecondNameNode = ET.SubElement(record, 'surname')
victimSecondNameNode.text = self.victimSecondName.get()
victimAddressNode = ET.SubElement(record, 'address')
victimAddressNode.text = self.victimAddress.get()
self.tree.write('crimeReport.xml')
self.clear_field()
def create_Widgets(self):
self.save = Button(self)
self.save["text"] = "Save",
self.save["command"] = self.save_XML
self.save["bg"] = "cyan"
self.save.grid(row=0,column =2,sticky=W+E+N+S)
self.crimeReportLabel = Label(self, text = 'Crime Report')
self.crimeReportLabel.grid(row=1,column =1,sticky=W)
self.caseNoLabel = Label(self,text="Case Number")
self.caseNoLabel.grid(row=2,column =1,sticky=W)
self.caseNo = Entry(self)
self.caseNo.grid(row=2,column =2,sticky=W)
self.victimDetailsLabel = Label(self,text="Victim Details")
self.victimDetailsLabel.grid(row=3,column =1,sticky=W)
self.victimFirstNameLabel = Label(self,text="First Name")
self.victimFirstNameLabel.grid(row=4,column =1,sticky=W)
self.victimFirstName = Entry(self)
self.victimFirstName.grid(row=4,column =2,sticky=W)
self.victimSecondNameLabel = Label(self,text="Surname")
self.victimSecondNameLabel.grid(row=4,column =3,sticky=W)
self.victimSecondName = Entry(self)
self.victimSecondName.grid(row=4,column =4,sticky=W)
self.victimAddressLabel = Label(self,text="Address")
self.victimAddressLabel.grid(row=6,column =1,sticky=W)
self.victimAddress = Entry(self)
self.victimAddress.grid(row=6,column =2,sticky=W)
def __init__(self, master = None):
Frame.__init__(self, master)
self.grid(column=5,row=25)
self.create_Widgets()
self.create_XML()
crimeReport = Tk()
app = Application(master = crimeReport)
app.mainloop()
crimeReport.destroy()
The error that I get is:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1532, in __call__
return self.func(*args)
File "C:\Users\Laleh\workspace\AdvDB20-02\program1\program1.py", line 60, in save_XML
record = ET.SubElement(self.crimeReport, 'crime report')
AttributeError: Application instance has no attribute 'crimeReport'
What the program is meant to do is create an XML file to use, for multiple entries by the user. Update and store the new entries in this XML file (not overriding the previous ones), so that later it can be searched and a report produced.
I'm a newbie to python and am not sure where I am going wrong?
Your application instance doesn't have any attribute named crimeReport
def save_XML(self):
record = ET.SubElement(self.crimeReport, 'crime report')
^
crimeReport is only defined in your create_XML method. You can define crimeReport as class attribute instead.
class Application(Frame):
crimeReport = Element('crime report')
and use self.crimeReport in your methods

Categories