Python GUI text editor - python

I have a GUI text editor i made with tkinter. It currently opens, saves and clears the screen. I have added an encrypt and decrypt button and will eventually apply the ceasar cipher to whatever text is on the screen.
For my encrypt button i so far have
def encrypt():
text = editor.get(1.0, tk.END)
encryptList = []
for word in text:
encryptList.append(word)
random.shuffle(encryptList)
return encryptList
What i am trying to have happen is to shuffle the text on my screen from whatever i have on there (im using a test file with "Test" printed a bunch of times) After I'm able to do this I can implement a cesar cipher to the text on the screen. (I hope)
whole code:
#Import Module
import random
import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfilename
from tkinter import ttk
#Create Function for New File Button
def fileNew():
editor.delete(1.0, tk.END)
#Create Function For Open File Button
def fileOpen():
editor.delete(1.0, tk.END)
filepath = askopenfilename(filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")])
with open(filepath, "r") as file:
text = file.read()
editor.insert(tk.END, text)
def encrypt():
text = editor.get(1.0, tk.END)
encryptList = []
for word in text:
encryptList.append(word)
random.shuffle(encryptList)
return encryptList
#Create Function For Save File Button
def fileSave():
save = asksaveasfilename(defaultextension=".*", filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")])
if not save:
return
with open(save, "w") as fileOutput:
text = editor.get(1.0, tk.END)
fileOutput.write(text)
#GUI
root = tk.Tk()
root.rowconfigure(0, minsize=500, weight=1)
root.columnconfigure(1, minsize=800, weight=1)
#Title
root.title()
#Text Editor
editor = tk.Text(root)
editor.configure(background="#263D42")
editor.grid(row=0, column=1, sticky="nsew")
#Scrollbar
scrollbar = ttk.Scrollbar(root, orient='vertical', command=editor.yview)
scrollbar.grid(row=0, column=2, sticky='ns')
#Left Side Panel
sidePanel = tk.Frame(root)
sidePanel.configure(background="#232e3a")
sidePanel.grid(row=0, column=0, sticky="ns")
#Open File Button
btn_open = tk.Button(sidePanel, text="Open", command=fileOpen)
btn_open.configure(background="#867c91")
btn_open.grid(row=0, column=0, sticky="ew", padx=5, pady=5)
#New File Button
btn_new = tk.Button(sidePanel, text="New", command=fileNew)
btn_new.configure(background="#867c91")
btn_new.grid(row=1, column=0, sticky="ew", padx=5, pady=5)
#Encrypt File Button
btn_open = tk.Button(sidePanel, text="Encrypt", command=encrypt)
btn_open.configure(background="#867c91")
btn_open.grid(row=2, column=0, sticky="ew", padx=5, pady=5)
#Decrypt File Button
btn_open = tk.Button(sidePanel, text="Decrypt")
btn_open.configure(background="#867c91")
btn_open.grid(row=3, column=0, sticky="ew", padx=5, pady=5)
#Save Button
btn_saveas = tk.Button(sidePanel, text="Save As", command=fileSave)
btn_saveas.configure(background="#867c91")
btn_saveas.grid(row=4, column=0, sticky="ew", padx=5, pady=5)
root.mainloop()

Closed. I figured it out
def encrypt():
text = editor.get(1.0, tk.END)
encryptList = []
for word in text:
encryptList.append(word)
random.shuffle(encryptList)
needed to add
editor.delete(1.0, tk.END)
editor.insert(tk.END, encryptList)

Related

Issues with managing entry box input with a list- Python tkinter

I'm working on a text editor application in Python tkinter. Every time a font is set, it is appended to a list. One of the features of the text editor is managing the font of the text. The issue is that after I change the font in one of the entry boxes, the next time I click on the Font button, The entry boxes input resets to its default input. Can someone help me find a solution for this issue? My code:
import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfilename
import tkinter.font as tkfont
from tkinter import messagebox
window = tk.Tk()
window.title("Text Editor")
window.configure(bg="white")
window.state("zoomed")
count = -1
my_list = []
def open_file():
file_path = askopenfilename(filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")])
if not file_path:
return
text_box.delete("1.0", tk.END)
with open(file_path, "r") as file_read:
text = file_read.read()
text_box.insert(tk.END, text)
def save_file():
file_path = asksaveasfilename(defaultextension="txt", filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")])
if not file_path:
return
with open(file_path, "w") as file_write:
text = text_box.get(1.0, tk.END)
file_write.write(text)
def font_command(default_font):
global count
count += 1
window2 = tk.Toplevel(window)
window2.title("Font Name")
window2.geometry("300x220+500+200")
font_n = tk.Label(window2, text="Font:", font=("Arial Rounded MT Bold", 10))
font_n.place(x=50, y=80)
name_entry = tk.Entry(window2)
name_entry.place(x=50, y=110)
font_size = tk.Label(window2, text="Font Size:", font=("Arial Rounded MT Bold", 10))
font_size.place(x=50, y=20)
size_entry = tk.Entry(window2)
size_entry.place(x=50, y=50)
font_color = tk.Label(window2, text="Font Color:", font=("Arial Rounded MT Bold", 10))
font_color.place(x=50, y=140)
color_entry = tk.Entry(window2)
color_entry.place(x=50, y=170)
color_entry.delete(0, tk.END)
color_entry.insert(tk.END, text_box["fg"])
ok_button = tk.Button(window2, text="OK", width=8, height=2, bg="white",
command=lambda: check_font(size_entry.get(), name_entry.get(), color_entry.get(), window2))
ok_button.place(x=210, y=100)
if count == 0:
name_entry.delete(0, tk.END)
name_entry.insert(tk.END, default_font["family"])
size_entry.delete(0, tk.END)
size_entry.insert(tk.END, default_font["size"])
my_list.append((name_entry.get(), size_entry.get()))
else:
name_entry.delete(0, tk.END)
name_entry.insert(tk.END, my_list[count - 1][0])
size_entry.delete(0, tk.END)
size_entry.insert(tk.END, my_list[count - 1][1])
my_list.append((name_entry.get(), size_entry.get()))
def check_font(size, font, color, root):
try:
font_settings = tkfont.Font(family=font, size=size)
text_box.configure(fg=color, font=font_settings)
root.destroy()
except:
messagebox.showerror("Font Error", "Invalid Font!")
frame = tk.Frame(window, bd=2, relief="raised")
frame.pack(side="left", fill="y")
default_f = tkfont.Font(family="Courier New", size=10)
text_box = tk.Text(window, font=default_f, fg="black")
text_box.pack(side="left", fill="both", expand=True)
scroll_bar = tk.Scrollbar(window, command=text_box.yview)
scroll_bar.pack(side="left", fill="y")
open_b = tk.Button(frame, text="Open", width=6, height=2, bg="white", command=open_file)
open_b.pack(padx=50, pady=(100, 5), anchor="n")
save_b = tk.Button(frame, text="Save As", width=6, height=2, bg="white", command=save_file)
save_b.pack(padx=50, pady=5)
font_info = tk.Button(frame, text="Font", width=6, height=2, bg="white", command=lambda: font_command(default_f))
font_info.pack(padx=50, pady=5)
text_box.configure(yscrollcommand=scroll_bar.set)
clear_text = tk.Button(frame, text="Clear All", width=6, height=2, bg="white",
command=lambda: text_box.delete(0, tk.END))
clear_text.pack(padx=50, pady=5)
window.mainloop()
I've managed to solve the problem with the help of #TheLizzard! The changes that I've made: I moved the my_list.append((font, size)) part to the try clause in the check_file function because I wanted to append the font attributes to the list only after the OK button was clicked, rather than right after creating the widgets in the font_command function. In the except clause, I'm also decrementing count by 1, so that if a user inputs a font which throws an error, it won't be counted.
Code:
import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfilename
import tkinter.font as tkfont
from tkinter import messagebox
window = tk.Tk()
window.title("Text Editor")
window.configure(bg="white")
window.state("zoomed")
count = -1
my_list = []
def open_file():
file_path = askopenfilename(filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")])
if not file_path:
return
text_box.delete("1.0", tk.END)
with open(file_path, "r") as file_read:
text = file_read.read()
text_box.insert(tk.END, text)
def save_file():
file_path = asksaveasfilename(defaultextension="txt", filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")])
if not file_path:
return
with open(file_path, "w") as file_write:
text = text_box.get(1.0, tk.END)
file_write.write(text)
def font_command(default_font):
global count
count += 1
window2 = tk.Toplevel(window)
window2.title("Font Name")
window2.geometry("300x220+500+200")
font_n = tk.Label(window2, text="Font:", font=("Arial Rounded MT Bold", 10))
font_n.place(x=50, y=80)
name_entry = tk.Entry(window2)
name_entry.place(x=50, y=110)
font_size = tk.Label(window2, text="Font Size:", font=("Arial Rounded MT Bold", 10))
font_size.place(x=50, y=20)
size_entry = tk.Entry(window2)
size_entry.place(x=50, y=50)
font_color = tk.Label(window2, text="Font Color:", font=("Arial Rounded MT Bold", 10))
font_color.place(x=50, y=140)
color_entry = tk.Entry(window2)
color_entry.place(x=50, y=170)
color_entry.delete(0, tk.END)
color_entry.insert(tk.END, text_box["fg"])
ok_button = tk.Button(window2, text="OK", width=8, height=2, bg="white",
command=lambda: check_font(size_entry.get(), name_entry.get(), color_entry.get(), window2))
ok_button.place(x=210, y=100)
if count == 0:
name_entry.delete(0, tk.END)
name_entry.insert(tk.END, default_font["family"])
size_entry.delete(0, tk.END)
size_entry.insert(tk.END, default_font["size"])
else:
name_entry.delete(0, tk.END)
name_entry.insert(tk.END, my_list[count - 1][0])
size_entry.delete(0, tk.END)
size_entry.insert(tk.END, my_list[count - 1][1])
def check_font(size, font, color, root):
global count
try:
font_settings = tkfont.Font(family=font, size=size)
text_box.configure(fg=color, font=font_settings)
root.destroy()
my_list.append((font, size))
except:
messagebox.showerror("Font Error", "Invalid Font!")
count -= 1
frame = tk.Frame(window, bd=2, relief="raised")
frame.pack(side="left", fill="y")
default_f = tkfont.Font(family="Courier New", size=10)
text_box = tk.Text(window, font=default_f, fg="black")
text_box.pack(side="left", fill="both", expand=True)
scroll_bar = tk.Scrollbar(window, command=text_box.yview)
scroll_bar.pack(side="left", fill="y")
open_b = tk.Button(frame, text="Open", width=6, height=2, bg="white", command=open_file)
open_b.pack(padx=50, pady=(100, 5), anchor="n")
save_b = tk.Button(frame, text="Save As", width=6, height=2, bg="white", command=save_file)
save_b.pack(padx=50, pady=5)
font_info = tk.Button(frame, text="Font", width=6, height=2, bg="white", command=lambda: font_command(default_f))
font_info.pack(padx=50, pady=5)
text_box.configure(yscrollcommand=scroll_bar.set)
clear_text = tk.Button(frame, text="Clear All", width=6, height=2, bg="white",
command=lambda: text_box.delete("1.0", tk.END))
clear_text.pack(padx=50, pady=5)
window.mainloop()

Updating label text in frame when job is finished

When pressing "Ping test" you get a new 'main window' with input and submit button.
when Submit is clicked, a file is created on the desktop and writes the output result of ping command.
right now, when I enter an address and click submit, I only see the menu frame and the main frame, the output frame shows up when the proccess is finished.
how can I make the output frame show "Pinging..." when I click the Submit button and update the label to "Ping Complete!" when its finished?
here's my code:
import tkinter as tk
import subprocess as sub
import easygui
import os
root = tk.Tk()
root.geometry("400x300")
# ===== Frame 1 - Left Menu =====
frame = tk.LabelFrame(root, text="Menu",height=80, width=40,
padx=5, pady=5, relief="solid")
frame.place(x=10, y=0)
# Show files button
showfilesButton = tk.Button(frame, text="Show Files", padx=5, pady=5,
command=lambda: showFiles())
showfilesButton.grid(row=1, column=0)
# ConvertURL button
convertURL = tk.Button(frame, text="Ping Test", padx=5, pady=5,
command=lambda: testPing.getURL())
convertURL.grid(row=2, column=0)
# Quit Button
endProgram = tk.Button(frame, text="Quit", padx=5, pady=5,
command=lambda: terminate())
endProgram.grid(row=3, column=0)
class testPing():
def __init__(self, host):
self.host = host
self.clearFile = clearFile
self.label = label
def getURL():
frame2 = tk.LabelFrame(root, text="Main Window", height=350, width=300, padx=30, pady=30)
frame2.pack()
urlLabel = tk.Label(frame2, text="Enter URL : ", padx=5, pady=5)
urlLabel.place(x=-30, y=-30)
urlInputBox = tk.Entry(frame2)
urlInputBox.pack()
clearLabel = tk.Label(frame2, text="Clear File?", padx=5, pady=5)
clearLabel.place(x=-30, y=20)
clearFile = tk.BooleanVar()
clearFile.set(False)
clearFileRadioYes = tk.Radiobutton(frame2, text="yes", value=True, var=clearFile,
command=lambda: testPing.callback(clearFile.get()))
clearFileRadioYes.place(x=-30, y=45)
clearFileRadioNo = tk.Radiobutton(frame2, text="no", value=False, var=clearFile,
command=lambda: testPing.callback(clearFile.get()))
clearFileRadioNo.place(x=20, y=45)
urlSubmitButton = tk.Button(frame2, text="Submit",
command=lambda: testPing.pingURL(urlInputBox.get(), clearFile.get()))
urlSubmitButton.pack(side=tk.RIGHT)
def callback(clearFile):
bul = clearFile
print(bul)
def pingURL(host, clearFile):
outputLabel = tk.LabelFrame(root, text="Output", height=35, width=150,
padx=5, pady=5, relief="solid")
outputLabel.place(x=0, y=150)
file = fr'c:/users/{os.getlogin()}/Desktop/ping.txt'
label = tk.Label(outputLabel, text=f'Pinging {host} ...')
label.grid(row=0, column=0)
clear = clearFile
if clear == True:
with open(file, 'w+') as output:
output.truncate(0)
sub.call(['ping', f'{host}'], stdout=output)
else:
with open(file, 'a') as output:
sub.call(['ping', f'{host}'], stdout=output)
output.close()
# testPing.changeLabel(host)
def changeLabel(host):
myLabel = tk.Label.config(text=f"Ping to {host} Complete!")
myLabel.pack()
def terminate():
exit()
def showFiles():
path = easygui.diropenbox() # Opens a folder dialog box.
folder = path
filelocation = f"c:\\Users\\{os.getlogin()}\\Desktop\\showFilesResult.txt"
filenames = os.listdir(folder) # Get the file names in the folder.
# Writing to file
with open(filelocation, 'a') as file:
for name in filenames:
file.write(f"Name: {name}\nFolder Path: {folder}\n!------------------------------!\n")
print("Done!")
root.mainloop()
Instead of calling changeLabel(), you can simply put:
output.close()
label.configure(text=f'Ping to {host} complete!')
# testPing.changeLabel(host)
But remember about updating your label first, if you don't at the end only complete label will be visible.
label = tk.Label(outputLabel, text=f'Pinging {host} ...')
label.grid(row=0, column=0)
label.update()
An additional tip, don't use different GUI creators in one project. If you only using easygui to get the path, check Tkinter methods -> askopenfilename and asksaveasfilename.

How to make the GUI using Tkinter of the format specified below?

In the code given below, I want to create a GUI in such a way that 1) In the top frame: 1st row : "x"(checkbutton), right to "x"(checkbutton) must be "Choose xFile"(button) and right to "Choose xFile"(button) must be "clear"(button) and likewise in the 2nd row : for "y". Only when the "x" checkbutton is checked, the "choose xFile" button should gets enabled. And when clicked upon "choose xFile", it has to open the file dialogbox. And the choosen file contents should get displayed using "description box" below the "Input data"(label) in the middle frame(with both horizontal and vertical scrollbar). And when "clear" button is clicked, only the selected file contents(x or y file choosen) in the "description box" must be cleared and it must enable the "Choose xFile"(button) or "Choose yFile"(button) to perform the task again(i.e to open the file dialog box). Below to the "description box" must contain "Reset" button and to the right of "Reset" button must be "Submit" button in the middle portion of the middle frame. When the "Reset" button is clicked, all the contents being displayed in the "description box" must be cleared and the all the checkboxes must be unchecked so that the user can perform the selection process again. In the bottom frame, below "Model Output"(label), a "description box" along with "horizontal" and "vertical" scrollbar must be there. Below to the "description box" must contain "Exit" button which is placed in the middle of the "bottom frame".
from tkinter import *
def forButton1():
filename1 = askopenfilename()
with open(filename1) as f:
for i in f:
myList.insert(END, i)
print(filename1)
def forButton2():
filename1 = askopenfilename()
with open(filename1) as f:
for i in f:
myList.insert(END, i)
print(filename1)
def forButton7():
root.destroy()
root = Tk()
root.title("Spatialization of DSSAT")
topFrame = LabelFrame(root, text = "Select input file")
MyVar1 = IntVar()
MyVar2 = IntVar()
MyCheckbutton1 = Checkbutton(topFrame, text="x", variable=MyVar1)
#MyCheckbutton1.grid(row=0, column=0)
MyCheckbutton1.pack()
MyCheckbutton2 = Checkbutton(topFrame, text="y", variable=MyVar2)
#MyCheckbutton2.grid(row=1, column=0)
MyCheckbutton2.pack()
Button1 = Button(topFrame, text = "Choose xFile", command = forButton1)
#button1.grid(row=0, column=1)
Button1.pack()
Button2 = Button(topFrame, text = "Choose yFile", command = forButton2)
#button2.grid(row=0, column=1)
Button2.pack()
Button3 = Button(topFrame, text = "Clear")
Button3.pack()
Button4 = Button(topFrame, text = "Clear")
Button4.pack()
topFrame.pack(side=TOP)
middleFrame = Frame(root)
label1 = Label(middleFrame, text = "Input data:")
label1.grid(row = 4)
scrollbar = Scrollbar(middleFrame)
myList = Listbox(middleFrame, yscrollcommand = scrollbar.set)
myList.pack()
scrollbar.config( command = myList.yview )
scrollbar.pack()
Button5 = Button(middleFrame, text = "Reset")
#button1.grid(row=0, column=1)
Button5.pack()
Button6 = Button(middleFrame, text = "Submit")
#button1.grid(row=0, column=1)
Button6.pack()
middleFrame.pack()
bottomFrame = Frame(root)
label2 = Label(bottomFrame, text = "Model Output:")
label2.grid(row = 10)
Button7 = Button(bottomFrame, text = "Exit", command = forButton7)
#button1.grid(row=0, column=1)
Button7.pack()
bottomFrame.pack()
root.geometry("500x500")
root.mainloop()
Here I have fixed the placement of the given widgets (not their functionalities) as asked in question. You can follow this way to get your desired format:
from tkinter import *
from tkinter import filedialog
def forButton1():
filename1 = filedialog.askopenfilename()
with open(filename1) as f:
for i in f:
myList.insert(END, i)
print(filename1)
def forButton2():
filename1 = filedialog.askopenfilename()
with open(filename1) as f:
for i in f:
myList.insert(END, i)
print(filename1)
def forButton7():
root.destroy()
root = Tk()
root.title("Spatialization of DSSAT")
root.grid_columnconfigure(0, weight=1)
topFrame = LabelFrame(root, text="Select input file")
topFrame.grid(row=0, column=0, padx=8, pady=8, sticky=N+E+S+W)
topFrame.grid_rowconfigure(0, weight=1)
topFrame.grid_rowconfigure(1, weight=1)
topFrame.grid_columnconfigure(0, weight=1)
topFrame.grid_columnconfigure(1, weight=1)
topFrame.grid_columnconfigure(2, weight=1)
middleFrame = LabelFrame(root, text="Input data")
middleFrame.grid(row=1, column=0, padx=8, pady=8, sticky=N+E+S+W)
middleFrame.grid_rowconfigure(0, weight=1)
middleFrame.grid_rowconfigure(1, weight=0)
middleFrame.grid_columnconfigure(0, weight=1)
middleFrame.grid_columnconfigure(1, weight=1)
bottomFrame = LabelFrame(root, text="Model Output")
bottomFrame.grid(row=2, column=0, padx=8, pady=8, sticky=N+E+S+W)
bottomFrame.grid_rowconfigure(0, weight=1)
bottomFrame.grid_columnconfigure(0, weight=1)
MyVar1 = IntVar()
MyVar2 = IntVar()
MyCheckbutton1 = Checkbutton(topFrame, text="x", variable=MyVar1)
MyCheckbutton1.grid(row=0, column=0, padx=4, pady=4)
Button1 = Button(topFrame, text="Choose xFile", command=forButton1)
Button1.grid(row=0, column=1, padx=4, pady=4)
Button3 = Button(topFrame, text="Clear")
Button3.grid(row=0, column=2, padx=4, pady=4)
MyCheckbutton2 = Checkbutton(topFrame, text="y", variable=MyVar2)
MyCheckbutton2.grid(row=1, column=0, padx=4, pady=4)
Button2 = Button(topFrame, text="Choose yFile", command=forButton2)
Button2.grid(row=1, column=1, padx=4, pady=4)
Button4 = Button(topFrame, text="Clear")
Button4.grid(row=1, column=2, padx=4, pady=4)
innerMiddleFrame = Frame(middleFrame)
innerMiddleFrame.grid(row=0, column=0, columnspan=2, padx=4, pady=4)
innerMiddleFrame.grid_columnconfigure(0, weight=1)
innerMiddleFrame.grid_columnconfigure(1, weight=0)
scrollbar = Scrollbar(innerMiddleFrame)
myList = Listbox(innerMiddleFrame, yscrollcommand=scrollbar.set)
myList.grid(row=0, column=0, sticky=N+E+S+W)
scrollbar.config(command=myList.yview)
scrollbar.grid(row=0, column=1, sticky=N+E+S+W)
Button5 = Button(middleFrame, text="Reset")
Button5.grid(row=1, column=0, padx=4, pady=4)
Button6 = Button(middleFrame, text="Submit")
Button6.grid(row=1, column=1, padx=4, pady=4)
Button7 = Button(bottomFrame, text="Exit", command=forButton7)
Button7.grid(row=0, column=0, padx=4, pady=4)
root.geometry("250x425")
root.mainloop()

Tkinter Filedialog.askopenfilename iteration

I am developing program to load up files and perform some calculations with those loaded files.
For that I wrote a simple iteration code to load the tkinter variables. The window, label, entry and button positions are already done. So far the code I have is:
import tkinter as tk
from tkinter import ttk, filedialog
LARGE_FONT = ("Arial", 12)
MEDIUM_FONT = ("Arial", 11)
REGULAR_FONT = ("Arial", 10)
text_z = ["Select file 1", "Select the file 2", "Select file 3", "Select file 4"]
window=tk.Tk()
def click():
z = tk.filedialog.askopenfilename(initialdir = "/",title = "Select file", filetypes = ( ("Excel file", "*.xlsx"), ("All files", "*.*") ) )
a[i-2].insert(tk.END, z)
z[i] = a[i-2].get()
##Main program
#There is an image I will add at the end on row=0
ttk.Label(window, text="file load", font = LARGE_FONT, background = "white").grid(row=1, column=1, columnspan=3, padx=20, pady = 10, sticky="W")
a = [tk.StringVar(window) for i in range(len(text_z))]
for i in range(2,len(text_z)+2):
Label_z = ttk.Label(window, text=text_z[i-2], background="white").grid(row= 2*i, column=0,columnspan=3, padx=10, pady=2, sticky="W")
a[i-2] = ttk.Entry(window, width=60, background="gray")
a[i-2].grid(row= 2*i+1, column=0, columnspan=3, padx=10, sticky="WE")
ttk.Button(window, text="Search", width=10, command=click).grid(row= 2*i+1, column=3, padx=5, sticky="W")
window.mainloop()
My problem is on the click button. It was supposed to during a click run the askopenfilename, get the file path and present on the entrybox, but all the buttons direct that to the last created Entrybox.
Can someone help me with this issue?
Thanks alot!
Lambda to the rescue. One needs to know the right Button-Entry pair to update. So pass the value of the corresponding index when a button is pressed.
import tkinter as tk
from tkinter import ttk, filedialog
LARGE_FONT = ("Arial", 12)
MEDIUM_FONT = ("Arial", 11)
REGULAR_FONT = ("Arial", 10)
text_z = ["Select file 1", "Select the file 2", "Select file 3", "Select file 4"]
window=tk.Tk()
def click(m):
z = tk.filedialog.askopenfilename(initialdir = "~",title = "Select file", filetypes = ( ("Text files", "*.txt"), ("All files", "*.*") ) )
a[m].insert(tk.END, z)
ttk.Label(window, text="file load", font = LARGE_FONT, background = "white").grid(row=1, column=1, columnspan=3, padx=20, pady = 10, sticky="W")
a = [None for i in range(len(text_z))]
for i in range(2,len(text_z)+2):
Label_z = ttk.Label(window, text=text_z[i-2], background="white").grid(row= 2*i, column=0,columnspan=3, padx=10, pady=2, sticky="W")
a[i-2] = ttk.Entry(window, width=60, background="gray")
a[i-2].grid(row= 2*i+1, column=0, columnspan=3, padx=10, sticky="WE")
ttk.Button(window, text="Search", width=10, command=lambda m=i-2:click(m)).grid(row= 2*i+1, column=3, padx=5, sticky="W")
window.mainloop()
I think you should simplify things a bit by use a list to store your entry fields.
To do this I think it would be best to add frames for each set of widgets and to use the index of range to get what we need.
I have changed up your code a little to make it easier to work with list index as well as added a button that will print out each selected path on each entry field to show these values are accessible.
import tkinter as tk
from tkinter import ttk, filedialog
LARGE_FONT = ("Arial", 12)
MEDIUM_FONT = ("Arial", 11)
REGULAR_FONT = ("Arial", 10)
text_z = ["Select file 1", "Select the file 2", "Select file 3", "Select file 4"]
window = tk.Tk()
def click(x):
z = tk.filedialog.askopenfilename(initialdir="/", title="Select file", filetypes=(("Excel file", "*.xlsx"), ("All files", "*.*")))
a[x].insert(tk.END, z)
ttk.Label(window, text="file load", font=LARGE_FONT, background="white").grid(row=1, column=0, padx=20, pady=10, sticky="w")
a=[]
for i in range(len(text_z)):
frame = tk.Frame(window)
frame.grid(row=i+2, column=0, sticky="nsew")
ttk.Label(frame, text=text_z[i], background="white").grid(row=0, column=0, columnspan=3, padx=10, pady=2, sticky="w")
a.append(ttk.Entry(frame, width=60, background="gray"))
a[i].grid(row=1, column=0, columnspan=3, padx=10, sticky="ew")
ttk.Button(frame, text="Search", width=10, command=lambda x=i: click(x)).grid(row=1, column=3, padx=5, sticky="w")
def pring_current_paths():
for ndex, entry in enumerate(a):
print("Entry {}: ".format(ndex, entry.get()))
tk.Button(window, text="Print gurrent paths!", command=pring_current_paths).grid()
window.mainloop()

Tkinter one button changes 2 entries

I'm building a simple application with Tkinter that has two browse buttons. One needs to be able to target a file and the other one only a folder. This works, but when I browse using either one button, it fills both of the entries. I'm new to Tkinter so I don't really understand why.
I'm using code from this question:
How to Show File Path with Browse Button in Python / Tkinter
This is my browse function:
def open_file(type):
global content
global file_path
global full_path
if type == "file":
filename = askopenfilename()
infile = open(filename, 'r')
content = infile.read()
file_path = os.path.dirname(filename)
entry.delete(0, END)
entry.insert(0, file_path+filename)
return content
elif type == "path":
full_path = askdirectory()
entry2.delete(0, END)
entry2.insert(0, full_path)
#return content
And this is my GUI code:
mf = Frame(root)
mf.pack()
f1 = Frame(mf, width=600, height=250)
f1.pack(fill=X)
f2 = Frame(mf, width=600, height=250)
f2.pack(fill=X)
Label(f1, text="Select Your File (Only txt files)").grid(row=0, column=0, sticky='e')
Label(f2, text="Select target folder").grid(row=0, column=0, sticky='e')
entry = Entry(f1, width=50, textvariable=file_path)
entry2 = Entry(f2, width=50, textvariable=full_path)
entry.grid(row=0, column=1, padx=2, pady=2, sticky='we', columnspan=25)
entry2.grid(row=0, column=1, padx=(67, 2), pady=2, sticky='we', columnspan=25)
Button(f1, text="Browse", command=lambda: open_file("file")).grid(row=0, column=27, sticky='ew', padx=8, pady=4)
Button(f2, text="Browse", command=lambda: open_file("path")).grid(row=0, column=27, sticky='ew', padx=8, pady=4)
How can I solve this problem? Thanks
Notice that the full_path (local variable in open_file method) has the same name as the global varibale.
You should use StringVar for text variables.
Change the initialization of both the file_path and full_path
global file_path
global full_path
file_path = StringVar()
full_path = StringVar()
Instead of those line:
entry.delete(0, END)
entry.insert(0, file_path+filename)
You can simply write:
full_path.set(file_path+filename)
Same with entry2, instead of:
elif type == "path":
full_path = askdirectory()
entry2.delete(0, END)
entry2.insert(0, full_path)
Write:
elif type == "path":
full_path_dir = askdirectory()
full_path.set(full_path_dir)

Categories

Resources