Tkinter entry.get() only works every 2 button clicks - python

I was making a simple flashcard tkinter application and I've encountered a problem such that when I manage the subjects, only every second item is added to the file.
For example, say I went to the manage subject page and I wanted to add the subjects: subject1, subject2, subject3, subject4, ... subjectN.
The only subjects that would add to the file are the subjects with the odd endings, is there a fix for this?
The code responsible for this:
#subjects window
def managesubjectsF():
def addF():
f = open ('subjectlist.txt', 'a')
f.write(addsubjectE.get() + '\n')
f.close()
addsubjectE.delete('0', 'end')
subjectPage = Tk()
subjectPage.title('Add subject')
subjectPage.resizable(False, False)
subjectPage.configure(background = 'light blue')
subjectPage.geometry('260x70')
addsubjectE = Entry(subjectPage, width=23, font=('bold', 14))
addsubjectE.grid(column=1, row=1)
addS = Button(subjectPage, text='Add', font=('bold', 15), command = addF)
addS.grid(column=1, row=2, sticky = N)
Minimal example of implementation:
#modules
from tkinter import *
import os.path
#implementations
count=0
subjectlist = []
#main window details
root = Tk()
root.geometry('225x350')
#list of available subjects
choice = Listbox(root, font = ('bold', 15))
choice.grid(column=1, row=2)
if os.path.exists('./subjectlist.txt') == True:
with open('subjectlist.txt', 'r') as f:
for line in f:
count += 1
f.close()
f = open('subjectlist.txt', 'r')
for i in range(count):
choice.insert(END, (f.readline().strip()))
subjectlist.append(f.readline().strip())
f.close()
else:
f = open('subjectlist.txt', 'w')
f.close()
#subjects window
def managesubjectsF():
def addF():
f = open ('subjectlist.txt', 'a')
f.write(addsubjectE.get() + '\n')
f.close()
addsubjectE.delete('0', 'end')
subjectPage = Toplevel()
subjectPage.geometry('260x70')
addsubjectE = Entry(subjectPage, width=23, font=('bold', 14))
addsubjectE.grid(column=1, row=1)
addS = Button(subjectPage, text='Add', font=('bold', 15), command = addF)
addS.grid(column=1, row=2, sticky = N)
#buttons
addsubjectsB = Button(root, text = 'Manage subjects', font = ('bold', 15), command = managesubjectsF)
addsubjectsB.grid(column=1, row=3, sticky = N)
root.mainloop()

(moving comment to answer)
You are calling readline twice which is moving the file pointer and skipping subjects.
for i in range(count):
choice.insert(END, (f.readline().strip()))
subjectlist.append(f.readline().strip()) # reading next line
Try reading the value once then storing in both lists:
for i in range(count):
s = f.readline().strip() # read once
choice.insert(END, (s))
subjectlist.append(s)

Related

Stuck trying to save a file from tkinter entry box into .txt file

Not really sure what im doing in this stage tbh, found someone asking a similar thing and tried to include it. However im not sure how to integrate it and at the moment they both do their own tkinter windows. One saving a .txt file, the other producing what ive written.
import sys
import tkinter as tk
from tkinter import *
from tkinter.messagebox import showinfo
root = tk.Tk()
root.wm_title('QR Code Generator')
def login():
frame = Frame(root)
Label(frame, text = "Welcome to QR Code Generator").grid(row = 0)
Label(frame, text = "Enter the link you want as a QR Code ").grid(row = 1)
e1 = Entry(frame)
e1.grid(row=1, column = 1)
Button(frame, text = 'Continue', command = save).grid(row = 4, column = 1, sticky = W, pady = 4)
return frame
def save():
file_name = entry.get()
with open(file_name + '.txt', 'w') as file_object:
file_object.write(file_name)
if __name__ == '__main__':
top = tk.Tk()
entry_field_variable = tk.StringVar()
entry = tk.Entry(top, textvariable=entry_field_variable)
entry.pack()
tk.Button(top, text="save", command=save).pack()
login_frame = login()
login_frame.pack(fill="both", expand=True)
root.mainloop()
wanting the "paste link for qr code" section to be saved into a .txt
Your filename is not defined anywhere in the code
I.e. your filename is empty, this results in a file with no name '.txt'
def save():
file_name = entry.get()
with open(file_name + '.txt', 'w') as file_object:
file_object.write(file_name)
Your code opens two windows, it is being created in this line, whenever you define another instance of Tk() it will be a new window, if you need it, I recommend Toplevel
if __name__ == '__main__':
top = tk.Tk()
Try something cleaner and easier to understand
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.wm_title('QR Code Generator')
def save():
content = e1.get()
with open('your_file.txt', 'w') as file_object:
file_object.write(content)
frame = Frame(root)
frame.pack()
Label(frame, text="Welcome to QR Code Generator").pack()
Label(frame, text="Enter the link you want as a QR Code ").pack()
e1 = Entry(frame)
e1.pack()
Button(frame, text='Continue', command=save).pack()
if __name__ == '__main__':
root.mainloop()
The qrcode is created as a picture. You can write a picture as base64 encoded to a text file, but I recommend to save the picture as an image.
I understood your request as "create" and "show" the saved picture into a tkinter window. I saved the picture with a timestamp.
My prototype:
import tkinter as tk
import qrcode
from PIL import ImageTk, Image
import time
root = tk.Tk()
root.title('QR Code Generator')
root.geometry("450x420")
#root.state("zoomed") whole display size
root.config(bg="#2c3e50")
#root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
def create_QR(link_input):
print(link_input.get())
lnk = link_input.get()
global qr_img
qr = qrcode.QRCode(version=1, error_correction = qrcode.constants.ERROR_CORRECT_L, box_size=10, border=3)
qr.add_data(lnk)
qr.make(fit=True)
time_str = str(int(time.time()))
img = qr.make_image(fill_color='cyan', back_color='#2c3e50')
img.save(f'qrcode_{time_str}.png')
qr_img = f'qrcode_{time_str}.png'
return qr_img
def show_qr():
global qr_img
qr_img = ImageTk.PhotoImage(Image.open(qr_img))
qr = tk.Label(frame, image = qr_img)
qr.grid(row =3, columnspan = 3, padx = 5, pady = 5)
qr.config(image = qr_img)
return qr_img
l1 = tk.Label(root, text = "Welcome to QR Code Generator", font=("Calibre", 16), bg="#2c3e50", fg="white")
l1.grid(row =0, columnspan = 2, padx = 5, pady = 5)
frame = tk.Frame(root)
frame.grid()
frame.config(bg="#2c3e50")
l2 = tk.Label(frame, text = "Link you want as a QR Code: ", bg="#2c3e50", fg="white")
l2.grid(row =1, column = 1, padx = 5, pady = 5, sticky="w")
link_name = tk.StringVar(frame, value='hhtps://')
e1 = tk.Entry(frame, textvariable = link_name, width=35)
e1.grid(row =1, column = 2, padx = 5, pady = 5)
b_cre = tk.Button(frame, text = 'Create QR Code', command = lambda: create_QR(link_name))
b_cre.grid(row =2, column = 1, padx = 5, pady = 5)
b_sav = tk.Button(frame, text = 'Show QR Code', command = show_qr)
b_sav.grid(row =2, column = 2, padx = 5, pady = 5)
root.mainloop()
Output:

string formatting is not working in tkinter

I have been trying to learn tkinter and have created something that post the results of a bunch of functions, and in the terminal the string formats works, but in the gui the string format does not work at all. I am super confused on why?
The code is below:
from tkinter import *
import ForFeesCovered
root = Tk()
root.title("Staff Fee Calculator")
root.geometry("375x400")
myLabel = Label(root,
text="Staff Fee Calculator")
e = Entry(root,
width=50,
borderwidth=5)
def output():
input_file = e.get()
f = ForFeesCovered.readfile(input_file)
file = ForFeesCovered.readfile(input_file)
staff = ForFeesCovered.getnamesofstaff(f)
staff.sort(reverse=False)
dic = ForFeesCovered.sort_dic(staff)
line_skip = 1
for lines in file:
line = lines.strip().split(",")
if line_skip != 1:
total = float("
{:.2f}".format(ForFeesCovered.getfeesforline(line)))
name = ForFeesCovered.get_name_of_staff(line, staff)
dic = ForFeesCovered.populating_dic(dic, name, total)
else:
line_skip += 1
string_dic = ""
result_file = open("result.txt", "w+")
for key in dic:
result_file.write("{} : {}\n".format(key, dic[key]))
string_dic = string_dic + "{:30} : {:>30}\n".format(key,
dic[key])
print(string_dic)
result_file.close()
output_dic = Label(root, text=string_dic, justify=LEFT)
output_dic.grid(row=2, column=0, pady=20)
submit = Button(root, text="Submit", command=output)
myLabel.grid(row=0, column=0)
e.grid(row=1, column=0,)
submit.grid(row=1, column=2)
root.mainloop()
The terminal is using a fixed-width font, the GUI is using a variable-width font.
If you are trying to line things up with spaces, you will need to used a fixed-width font.

python tkinter interface how to create a new to show txt file

I buid a code which takes python user input and insert it into a text file when pressing apply as shown in the picture bellow
and the text file will always be updated when the user inserts a new text, how to create an new button next to apply to show up to date text file to the user
and want prevent to enter the same text
example if the text file has a (go) the program do not enter (go) again
this is my code
root = Tk()
ivn = StringVar()
inputVarName = Entry(root, textvariable=str(ivn))
ivn.set(str("text1"))
inputVarName.grid(row=0, column=0)
ivn2 = StringVar()
inputVarName2 = Entry(root, textvariable=str(ivn2))
ivn2.set(str("text2"))
inputVarName2.grid(row=1, column=0)
def writetofile():
content_list = [ivn.get(), ivn2.get()]
print("\n".join(content_list))
with open("help.txt", "a") as f:
for item in content_list:
f.write("%s\n" % item)
applyButton = Button(root, text="Apply", command=writetofile)
applyButton.grid(row=2, column=1)
root.mainloop()
To prevent a user from inserting the same text just empty the two entries, and you can check if entries are not empty before saving to a file.
You can use a top-level window to show the file content.
Check the following example:
from tkinter import Tk, Toplevel, Button, Entry, StringVar, Text, DISABLED, END, W, E
import tkinter.ttk as ttk
import tkMessageBox
root = Tk()
ivn = StringVar()
inputVarName = Entry(root, textvariable=str(ivn))
ivn.set(str("text1"))
inputVarName.grid(row=0, column=0,columnspan=2)
ivn2 = StringVar()
inputVarName2 = Entry(root, textvariable=str(ivn2))
ivn2.set(str("text2"))
inputVarName2.grid(row=1, column=0,columnspan=2)
def writetofile():
content_list = [ivn.get(), ivn2.get()]
if any(content_list):
print("\n".join(content_list))
with open("help.txt", 'r+') as inFile:
for item in content_list:
if ("%s\n" % item).encode('UTF-8') in inFile:
tkMessageBox.showwarning("Warning", "'%s': Already exists!" % item)
return
with open("help.txt", "a") as f:
for item in content_list:
f.write( ("%s\n" % item).encode('UTF-8'))
ivn.set('')
ivn2.set('')
def showfile():
top = Toplevel()
top.title("help.txt")
textArea = Text(top)
scrollbar = ttk.Scrollbar(top, command=textArea.yview)
scrollbar.grid(row=0, column=1, sticky='nsew')
textArea['yscrollcommand'] = scrollbar.set
with open("help.txt", "r") as infile:
textArea.insert(END, infile.read())
textArea.grid(row=0, column=0)
textArea.config(state=DISABLED)
applyButton = Button(root, text="Apply", command=writetofile)
applyButton.grid(row=2, column=0, sticky=W+E)
showButton = Button(root, text="Show", command=showfile)
showButton.grid(row=2, column=1, sticky=W+E)
root.mainloop()
Edited to answer #IbrahimOzaeri question in comments.
You can use tkFileDialog.askopenfilename to ask user to select a file:
from Tkinter import Tk
import Tkinter, Tkconstants, tkFileDialog
root = Tk()
root.filename = tkFileDialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = (("text files","*.txt"),("all files","*.*")))
print (root.filename)
I was trying something same but with one output
import tkinter.ttk as ttk
import tkMessageBox
root = Tk()
root.geometry("500x300")
root.title("The Gatway company")
ivn = StringVar()
inputVarName = Entry(root, textvariable=str(ivn))
ivn.set(str("text1"))
inputVarName.grid(row=0, column=0,columnspan=2)
def writetofile():
content_list = [ivn.get()]
if any(content_list):
with open("help.txt", 'r+') as inFile:
for item in content_list:
if ("%s\n" % item).encode('UTF-8') in inFile:
tkMessageBox.showwarning("Warning", "'%s': Already exists!" % item)
return
with open("help.txt", "a") as f:
for item in content_list:
f.write( ("%s\n" % item).encode('UTF-8'))
ivn.set('')
def showfile():
top = Toplevel()
top.title("help.txt")
textArea = Text(top)
scrollbar = ttk.Scrollbar(top, command=textArea.yview)
scrollbar.grid(row=0, column=1, sticky='nsew')
textArea['yscrollcommand'] = scrollbar.set
with open("help.txt", "r") as infile:
textArea.insert(END, infile.read())
textArea.grid(row=0, column=0)
textArea.config(state=DISABLED)
applyButton = Button(root, text="Apply", command=writetofile)
applyButton.grid(row=2, column=0, sticky=W+E)
applyButton.config( height = 5, width = 10 )
showButton = Button(root, text="Show", command=showfile)
showButton.grid(row=2, column=1, sticky=W+E)
showButton.config( height = 5, width = 10 )
root.mainloop()
it's same as your code but for one entry, I'm thinking to edit it in a such way that the user chooses the help.txt file like a file requester.

Arithmetic Summation in the file operations using Python Tkinter

please help me run arithmetic summation in the file operations using Python Tkinter
input should be here (in the textbox)
summation output should be in TXT file
Source Code :
INPUT
topup = tkinter.StringVar()
TextBox_1 = ttk.Entry(jendela, width=20, textvariable=topup)
TextBox_1.grid(column = 1, row = 3)
BUTTON
def clickhere():
f = open("TOPUP", "r")
w = f.readline()
f.close()
f = open("TOPUP", 'r+')
t=int(w)+ (topup.get())
f.write(str(t))
f.close()
button_ = ttk.Button(jendela, text='Top up!', command=lambda : clickhere, width=17)
button_.grid(column=2, row=3)
try this code:
from tkinter import *
root= Tk()
topup = StringVar()
TextBox_1 = Entry(root, width=20, textvariable=topup)
TextBox_1.grid(column = 1, row = 3)
def clickhere():
f = open("TOPUP.txt", "r+")
w = f.readline()
t=int(w)+ int(topup.get())
f.seek(0)
f.truncate()
f.write(str(t))
f.close()
button_ = Button(root, text='Top up!', command=clickhere, width=17)
button_.grid(column=2, row=3)

How to attribute a button the function to get text from an output file?

What I need is to make the view orders button to get the text from the Customer.txt file and set it inside a textfield i made.
#make order,cancel,view
from tkinter import *
import tkinter.messagebox
root = Tk()
file = open("Customer.txt", "w")
def textW():
outFile = open("Customer.txt", "wt")
def CancelOrder():
outFile=open("Customer.txt", "w")
outFile.write("")
tkinter.messagebox.showinfo("Cancel Order", "Your order has been canceled")
def ViewOrder():
outFile = open('Customer.txt', 'r')
test = outFile.read()
#tViewOrder.set(test)
print (test)
#test.set(tViewOrder)
#outFile.close()
def MakeOrder():
outFile=open("Customer.txt", "w")
outFile.write("" + tMakeOrder.get())
tkinter.messagebox.showinfo("Make Order", "Order has been placed. Thank you!")
#Labels
lMakeOrder = Label(root, text="Make an order")
lViewOrder = Label(root, text="View Order")
#TextFields
tMakeOrder = Entry(root)
tViewOrder = Entry(root, state="disabled")
#Buttons
bMakeOrder = Button(root, text="Make order",bg="black",fg="green", command=MakeOrder)
bCancelOrder = Button(root, text="Cancel order",bg="black",fg="green", command=CancelOrder)
bViewOrder = Button(root, text="View orders",bg="black",fg="green", command=ViewOrder)
#Position
lMakeOrder.grid(row=0)
lViewOrder.grid(row=1)
tMakeOrder.grid(row=0, column=2)
tViewOrder.grid(row=1, column=2)
bMakeOrder.grid(row=4)
bViewOrder.grid(row=4, column=2)
bCancelOrder.grid(row=4, column=4)
#Window stuff
root.title("Sky is a shit name service - Customer")
root.geometry("300x300")
root.mainloop()
You can put text inside your Entry by calling insert function on it.
MyEntry.insert(POSITION, TEXT)
Oh and one more thing. You can't insert anything in the entry if it's disabled.
So here is your modified function:
def ViewOrder():
outFile = open('Customer.txt', 'r')
test = outFile.read()
tViewOrder['state'] = 'normal'
tViewOrder.delete(0, 'end') #Remove everything before
tViewOrder.insert(0, test)
tViewOrder['state'] = 'disabled'
outFile.close()

Categories

Resources