Related
I tried adding a text file to store all the data by building a function that opens and writes data to the file, the code seems to run but no data is getting added to the text file.
Here is the tkinter code.
name = StringVar()
email = StringVar()
usn = StringVar()
namelabel = ttk.Label(frame_content, text='Name',font=('Poppins', 10))
namelabel.grid(row=0, column=0, sticky='sw', padx=(2,10))
entry_name = ttk.Entry(frame_content, width=30, font=('Poppins', 10), textvariable=name)
entry_name.grid(row=1, column=0)
emaillabel = ttk.Label(frame_content, text='Email',font=('Poppins', 10))
emaillabel.grid(row=0, column=1, sticky='sw', padx=10)
entry_email = ttk.Entry(frame_content, width=30, font=('Poppins', 10), textvariable=email)
entry_email.grid(row=1, column=1, padx=10)
usnlabel = ttk.Label(frame_content, text='USN',font=('Poppins', 10))
usnlabel.grid(row=0, column=2, sticky='sw')
entry_usn = ttk.Entry(frame_content, width=30, font=('Poppins', 10), textvariable=usn)
entry_usn.grid(row=1, column=2)
feedbacklabel = ttk.Label(frame_content, text='Feedback', font=('Poppins', 10))
feedbacklabel.grid(row=2, column=0, sticky='sw', pady=5)
textfeedback = Text(frame_content, width=94, height=15, font=('Poppins', 10))
textfeedback.grid(row=3, column=0, columnspan=3)
def submit():
print('Name:{}'.format(name.get()))
print('USN:{}'.format(usn.get()))
print('Email:{}'.format(email.get()))
print('Feedback:{}'.format(textfeedback.get(1.0, END)))
messagebox.showinfo(title='Submit', message='Thank you for your Feedback')
entry_name.delete(0, END)
entry_email.delete(0, END)
entry_usn.delete(0, END)
textfeedback.delete(1.0, END)
def open_file():
name_info = name.get()
email_info = email.get()
usn_info = usn.get()
feed_info = textfeedback.get(1.0, END)
data_file = open("data.txt", 'w')
data_file.write(name_info)
data_file.write(email_info)
data_file.write(usn_info)
data_file.write(feed_info)
data_file.close()
submitbutton = ttk.Button(root, width=25, text='Submit', command=lambda: [submit(), open_file()])
mainloop()
EDIT
Your mistake can be at
submitbutton = ttk.Button(root, width=25, text='Submit', command=lambda: [submit(), open_file()])
Call open_file() function first, then call submit() function, like:
submitbutton = ttk.Button(root, width=25, text='Submit', command=lambda: [open_file(), submit()])
This question already has answers here:
tkinter creating buttons in for loop passing command arguments
(3 answers)
Closed last year.
from tkinter import *
from Createwindow import *
button_name = ""
def click():
window = Tk()
window.geometry("600x500")
frame = Frame(window, bg = "#161853", width = 600, height = 500)
row_ = 0
column_ = 0
list = []
with open ("Passwords.txt", 'r') as data_file:
data = data_file.readlines()
for i in data:
names = i.split("|")
list.append(names[0])
for i in range(len(list)):
name = list[i]
button_ = Button(frame,text=name, font=("Helvetica", 12), width=16, bg="white", fg="black", command=create_window)
button_.grid(row=row_, column=column_, padx=(25, 0), pady=(25,0))
column_ += 1
if column_ == 3:
row_ += 1
column_ = 0
button_name = button_.cget('text')
frame.pack(fill="both", expand=True)
window.mainloop()
def create_window():
def fill_fields():
with open ("Passwords.txt", 'r') as data_file:
data = data_file.readlines()
for i in data:
names = i.split("|")
if names[0] == button_name:
Website_.insert(0, names[0])
Username_.insert(0, names[1])
Password_.insert(0, names[2])
def save_password():
if Website_.get() == "" or Username_.get() == "" or Password_.get() == "":
window = Tk()
Error_Message = Label(window, text = "Error! Please fill all the above fields.", bg="red", fg="white", font=("Arial", 16))
Error_Message.pack()
window.mainloop()
else:
with open("Passwords.txt" , 'a') as file:
file.write(Website_.get() + "|" + Username_.get() + "|" + Password_.get() + "\n")
window = Tk()
window.geometry("600x500")
window.configure(bg="#161853")
window.minsize(600, 500)
frame = Frame(window, bg="#161853")
frame.rowconfigure(2, weight=1)
frame.columnconfigure([0, 1, 2], weight=1)
Text = Label(frame, text="Save your password here", font=("Helvetica", 14), fg="white", bg="#161853")
Text.grid(row=0, column=1, pady=(0,25))
Website = Label(frame, text="Website:", font=("Helvetica", 14), fg="white", bg="#161853")
Website.grid(row=1, column=0, padx=(0, 15), pady=(0,20))
Website_ = Entry(frame, width=25)
Website_.grid(row=1, column=1, pady=(0, 20))
Username = Label(frame, text="Username/Email:", font=("Helvetica", 14), fg="white", bg="#161853")
Username.grid(row=2, column=0, padx=(0, 15), pady=(0, 20))
Username_ = Entry(frame, width=25)
Username_.grid(row=2, column=1, pady=(0, 20))
Password = Label(frame, text="Password:", font=("Helvetica", 14), fg="white", bg="#161853" )
Password.grid(row=3, column=0, padx=(0, 15), sticky="s")
Password_ = Entry(frame, width=25)
Password_.grid(row=3, column=1, pady=(0, 30), sticky="s")
Generate = Button(frame, text="Generate Password", font=("Helvetica", 12), width=16)
Generate.grid(row=3, column=2, sticky="s")
Save = Button(frame, text="Save Password", font=("Helvetica", 12), width=14, command=save_password)
Save.grid(row=4, column=1)
frame.place(relx=0.5, rely=0.5, anchor="center")
fill_fields()
window.mainloop()
In this piece of code basically I am creating a window where all the passwords saved in password.txt file will appear.
The code creates a button on the name of the website whose password is saved.
What I want to do is that when that button is clicked I want to get the text of the clicked button bcoz all the buttons are created automatically they have same name and the text of button is the one that is created in the last iteration.
You may pass the argument while adding click event in dynamic generated button.
for example below is your old code:
button_ = Button(frame,text = name , font = ("Helvetica", 12), width = 16, bg = "white" , fg = "black", command= create_window)
If you want to get the value of name when click on this button. Just do as like below:
button_ = Button(frame,text = name , font = ("Helvetica", 12), width = 16, bg = "white" , fg = "black", command= create_window(name))
Here i'm adding name argument in create_window function.
That i had already impletemented in my project and its working fine. Please try it and let me know if you will face any issue.
Please check below link for more details.
https://www.delftstack.com/howto/python-tkinter/how-to-pass-arguments-to-tkinter-button-command/
l have to develop an interactive program which lets its users select from
several ranked HTML lists and using widgets to pick out certain HTML code to display the current 2nd position in each lists. Each widget is too show a differnet list from a different HTML website each time. I have set up all my widgets and my GUI but I am unsure on how to complete this task of each widget pulling HTML code and displaying it in a window.
The main things I am having problems with are, pulling HTML code from a live website and displaying this using my radiobutton widgets. Hopefully someone can point me in the right direction.
Here is the code that I have completed so far
root = Tk()
root.title("Runners Up")
root.config(background = "#f0f0f0")
test_status0 = BooleanVar()
test_status1 = BooleanVar()
test_status2 = BooleanVar()
test_status3 = BooleanVar()
test_status4 = BooleanVar()
#Label Frame for Radio Buttons
radiobuttonsframe = LabelFrame(root, relief = 'groove', font = 'Arial',
borderwidth = 5)
radiobuttonsframe.grid(row=0, column=1, padx=10, pady=2)
#Picture Label Frame
PicFrame = LabelFrame(root, relief = 'groove', borderwidth = 5)
PicFrame.grid(row=0, column=0, padx=10, pady=2)
#Display Frame (Runner Up)
RunnerFrame = LabelFrame(root, relief = 'groove', borderwidth = 5, font = 'Arial',
text = 'Runner Up')
RunnerFrame.grid(row=1, column=0, padx=10, pady=2)
#Display Frame (Full List)
ListFrame = LabelFrame(root, relief = 'groove', borderwidth = 5, font = 'Arial',
text = 'Full List')
ListFrame.grid(row=1, column=1, padx=10, pady=2)
#Importing Photo
Picture1 = PhotoImage(file="Secondplace.gif")
Label(PicFrame, image=Picture1).grid(row=0, column=0, padx=10, pady=2)
#Frames for each widget
btnFrame = LabelFrame(radiobuttonsframe, relief = 'groove',
font = 'Arial', borderwidth = 2, text = 'Current Runner Ups', background="#f0f0f0")
btnFrame.grid(row=1, column=0, padx=10, pady=2)
btnFramePrev = LabelFrame(radiobuttonsframe, relief = 'groove',
font = 'Arial', borderwidth = 2, text = 'Previous Runner Ups', background="#f0f0f0")
btnFramePrev.grid(row=2, column=0, padx=10, pady=50)
updaterBtn = LabelFrame(radiobuttonsframe, relief = 'groove',
font = 'Arial', borderwidth = 2, background="#f0f0f0")
updaterBtn.grid(row=3, column=0, padx=10, pady=2)
#Button Music Runner ups
MusicButton = Radiobutton(btnFrame, text="Top Album Charts [Title and Artist]",
height=2, width=50, value = test_status1, command = test1)
MusicButton.grid(row=0, column=0, padx=10, pady=2)
#Button for Movie Runner ups
MovieButton = Radiobutton(btnFrame, text="Movie Charts [Title and Production]",
height=2, width=50, value = test_status2, command = test1)
MovieButton.grid(row=1, column=0, padx=10, pady=2)
#Button for games runner ups
GamesButton = Radiobutton(btnFrame, text="Game Charts [Title and Players]",
height=2, width=50, value = test_status3, command = test1)
GamesButton.grid(row=2, column=0, padx=10, pady=2)
#Button for Medal runner ups
MedalButton = Radiobutton(btnFramePrev, text="Medal 2001 [Name and Votes]",
height=2, width=50, value = test_status4, command = test1)
MedalButton.grid(row=3, column=0, padx=10, pady=2)
#Scroll Bar for full list of winners
ListScroll = ScrolledText(ListFrame, width=40, height=10)
ListScroll.grid(row=0, column=0, padx=10, pady=2)
#Text Box for our main Runners Up
RunnersText = Text(RunnerFrame, width=50, height=10)
RunnersText.grid(row=0, column=0, padx=10, pady=2)
#Update and Show Source Buttons
Update = Button(updaterBtn, text="Update", height=2, width=10)
Update.grid(row=0, column=0, padx=10, pady=2)
ShowSource = Button(updaterBtn, text="Show Source", height=2, width=10)
ShowSource.grid(row=0, column=1, padx=10, pady=2)
root.mainloop()
\EDIT//
I've figured out to run the buttons but now I am having trouble actually getting the HTML text to display in my text box.
Here is my attempt at trying that:
def MusicRunner():
RunnersText.delete(0.0, END)
site = 'Official Charts'
feed_web = download('https://www.officialcharts.com/charts/singles-chart/')
items = findall(r'<body class="sticky-nav" style \b[^>]*>(.*?)<\/body>', feed_web, flags=MULTILINE|DOTALL)
num = findall(r'<span class= "position">"2"</span>',feed_web, flags=MULTILINE|DOTALL)
RunnersText.insert(INSERT, num)
I am learning python/tkinter and as a project I am trying to create a GUI to edit mp3 tags.
I have a for loop that will go through all directories/files in a directory and for each file return the tags.
I also have a tkinter code that will create a window with labels, buttons and a text box to provide a new tag. Right now I am focusing on the genre tag but I plan to expand this as I continue to build this code.
I want a GUI that displays the tags from a file and allows for new text to be entered that will be written to the mp3 when I press the update button as well as getting the information on the next file in the directory to be edited.
Separately my codes are working. When I try to put the os.walk loop into the tkinter mainloop it isn't working. I get the feeling that I am approaching this wrong.
Can someone help me understand what is wrong with my approach?
loop through files
import mutagen
import os
list_of_genres = []
for root, dirs, files in os.walk('C:\Music'):
for name in files:
music_file = os.path.join(root, name)
try:
filetags = mutagen.File(music_file, easy = True)
genre = filetags.tags['genre']
list_of_genres.append(genre)
except:
list_of_errors.append(music_file)
list_of_genres
tkinter gui
from tkinter import *
def click():
#this collects the text from the text entry box
entered_text=textentry.get()
output.delete(0.0, END)
#try:
#except:
def close_window():
window.destroy()
#exit() #### This will kill kernel
# main:
window = Tk()
window.title('Genre Editor v.0001')
window.configure(background='black')
# my photo
photo1 = PhotoImage(file = 'C:\Music\Blank 185\Dido Ranch\AlbumArtSmall.gif')
# create labels
Label (window, image=photo1, bg='black') .grid(row=0)
Label(window, text = 'Artist: ', bg='black',
fg='white', font='none 12 bold').grid(row=1, sticky=W)
Label(window, text = 'Current Genre: ', bg='black',
fg='white', font='none 12 bold').grid(row=2, sticky=W)
Label(window, text = 'New Genre: ', bg='black',
fg='white', font='none 12 bold').grid(row=3, sticky=W)
# box for text input
textentry = Entry(window, width=30,
bg='white') .grid(row=3, column=1, columnspan=2)
# action buttons
Button(window, text='Quit', width=15, command=close_window
).grid(row=4, column = 0, padx=5, pady=5, sticky=W)
Button(window, text='No Change', width=15, command=''
).grid(row=4, column = 1, padx=5, pady=5, sticky=W)
Button(window, text='Update Genre', width=15, command=click
).grid(row=4, column = 2, padx=5, pady=5, sticky=W)
window.mainloop()
Attempt to mix the two
import os
from tkinter import *
import mutagen
def click():
entered_text=textentry.get()
output.delete(0.0, END)
def close_window():
window.destroy()
# main:
window = Tk()
window.title('Genre Editor v.0001')
window.configure(background='black')
list_of_errors = []
list_of_genres = []
for root, dirs, files in os.walk('C:\Music'):
for name in files:
music_file = os.path.join(root, name)
try:
filetags = mutagen.File(music_file, easy = True)
photo1 = PhotoImage(
file = 'C:\Music\Blank 185\Dido Ranch\AlbumArtSmall.gif')
Label (window, image=photo1, bg='black') .grid(row=0)
Label(window, text = 'Artist: '+ artist, bg='black',
fg='white', font='none 12 bold').grid(row=1, sticky=W)
Label(window, text = 'Current Genre: '+ genre,
bg='black', fg='white', font='none 12 bold').grid(row=2,
sticky=W)
Label(window, text = 'New Genre: ', bg='black',
fg='white', font='none 12 bold').grid(row=3, sticky=W)
textentry = Entry(window, width=30, bg='white'
) .grid(row=3, column=1, columnspan=2)
Button(window, text='Quit', width=15, command=close_window
).grid(row=4, column = 0, padx=5, pady=5, sticky=W)
Button(window, text='No Change', width=15, command=''
).grid(row=4, column = 1, padx=5, pady=5, sticky=W)
Button(window, text='Update Genre', width=15, command=click
).grid(row=4, column = 2, padx=5, pady=5, sticky=W)
except:
list_of_errors.append(music_file)
window.mainloop()
The main issue with the code is the file loop. GUI applications are event based so the button must be used to move to the next file. For the controls, build them once then update the values when a new file is loaded.
Try this code. It loads the tag data into the form for each file.
import os
from tkinter import *
import mutagen
def click(): # next file
global lblArtist,lblGenre,lblNewGenre,curFile
entered_text=textentryVar.get()
#output.delete(0.0, END) # what does this do ?
while curFile < len(lstFile):
curFile += 1
try:
load_file(curFile) # next file
break # load success
except Exception as ex:
print("Load failed:", lstFile[curFile], ex)
curFile += 1 # go to next file
else: # done files
lblArtist['text'] = "--- Done All Files ---"
lblGenre['text'] = ""
def close_window():
window.destroy()
def load_file(i): # load tags
global lblArtist,lblGenre,lblNewGenre
filetags = mutagen.File(lstFile[i], easy = True)
print(lblArtist)
lblArtist['text'] = filetags['artist'][0]
lblGenre['text'] = filetags['genre'][0]
lblNewGenre['text'] = ""
lstFile = []
for root, dirs, files in os.walk(r'C:\Music'): # all files in folder
for name in files:
lstFile.append(os.path.join(root, name))
# main:
window = Tk()
window.title('Genre Editor v.0001')
window.configure(background='black')
# build form
lblArtist = Label(window, text = 'Artist: ', bg='black', fg='white', font=("times", 12, "bold"))
lblArtist.grid(row=1, sticky=W)
lblGenre = Label(window, text = 'Current Genre: ', bg='black', fg='white', font=("times", 12, "bold"))
lblGenre.grid(row=2, sticky=W)
lblNewGenre = Label(window, text = 'New Genre: ', bg='black', fg='white', font=("times", 12, "bold"))
lblNewGenre.grid(row=3, sticky=W)
textentryVar = StringVar() # entry box needs linked variable
textentry = Entry(window, textvariable=textentryVar, width=30, bg='white' ) .grid(row=3, column=1, columnspan=2)
Button(window, text='Quit', width=15, command=close_window ).grid(row=4, column = 0, padx=5, pady=5, sticky=W)
Button(window, text='No Change', width=15, command='' ).grid(row=4, column = 1, padx=5, pady=5, sticky=W)
Button(window, text='Update Genre', width=15, command=click ).grid(row=4, column = 2, padx=5, pady=5, sticky=W)
list_of_errors = []
list_of_genres = []
# start file counter
curFile = 0
load_file(curFile) # load first file
window.mainloop()
Very simple, don't be impressed by the size of the code.
I want to do something very simple (well, not for me, since I'm asking for help here) put the location of the open file in the red square on the screen:
Screen
import tkinter as tk
from tkinter.filedialog import askopenfilename
from tkinter import messagebox
def OpenFile_AntiDuplicate():
global antiduplicate_file
mainframe = tk.Frame(bg='#1c2028')
antiduplicate_file = askopenfilename(initialdir="/",
filetypes =(("Text file", "*.txt"),("All files","*.*")),
title = "Open text file"
)
fichier_dir = tk.Label(mainframe, text=antiduplicate_file).pack()
try:
with open(antiduplicate_file,'r') as UseFile:
print(antiduplicate_file)
except:
print("Non-existent file")
def RUN_AntiDuplicate():
try:
with open(antiduplicate_file,'r') as UseFile:
print(antiduplicate_file)
except:
error1 = tk.messagebox.showerror("ERROR", "No files exist!")
#----------------------------------------------------------
class HoverButton(tk.Button):
def __init__(self, master, **kw):
tk.Button.__init__(self,master=master,**kw)
self.defaultBackground = self["background"]
self.bind("<Enter>", self.on_enter)
self.bind("<Leave>", self.on_leave)
def on_enter(self, e):
self['background'] = self['activebackground']
def on_leave(self, e):
self['background'] = self.defaultBackground
#----------------------------------------------------------
def Anti_Duplicate():
mainframe = tk.Frame(bg='#1c2028')
mainframe.grid(row=0, column=0, sticky='nsew')
bouton_1 = HoverButton(mainframe, font=("Arial", 10), text="Back",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#CF3411',
relief='ridge', command=mainframe.destroy)
bouton_1.place(x=520, y=300)
open_button = HoverButton(mainframe, font=("Arial", 10), text="Open File..",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command = OpenFile_AntiDuplicate)
open_button.place(x=284.3, y=200, anchor='n')
run_button = HoverButton(mainframe, font=("Arial", 20), text="RUN",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#11CF6D',
relief='ridge', command = RUN_AntiDuplicate)
run_button.place(x=50, y=330, anchor='s')
bouton_2 = tk.Button(mainframe, font=("Arial", 10),
text="The purpose of this tool is to remove duplicate lines from a text file.",
background='#202124', fg='#1195cf', borderwidth=2,
activebackground= '#202124', activeforeground='#1195cf', relief='sunken')
bouton_2.place(relx=.5, y=50, anchor='n')
bouton_1 = tk.Button(mainframe, font=("Arial", 15), text="Anti-Duplicate",
background='#202124', fg='#1195cf', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf', relief='sunken')
bouton_1.pack(side= "top", padx= 5, pady=5, ipadx= 30, anchor="n")
#----------------------------------------------------------
def main_menu():
root = tk.Tk()
screenn_x = int(root.winfo_screenwidth())
root.config(background='#1c2028')
screenn_y = int(root.winfo_screenheight())
root.title("ComboKit v0.0.1")
root.minsize(570, 340)
root.resizable(0,0)
windowss_x = 570
windowss_y = 340
possX = (screenn_x // 2) - (windowss_x // 2)
possY = (screenn_y // 2) - (windowss_y // 2)
geoo = "{}x{}+{}+{}".format(windowss_x, windowss_y, possX, possY)
root.geometry(geoo)
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
mainframe = tk.Frame(root, bg='#1c2028')
mainframe.grid(row=0, column=0, sticky='n')
main_fusion_bouton = HoverButton(mainframe, font=("Arial", 15), text="Fusion",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command=None)
main_fusion_bouton.pack(side= "left", padx= 5, pady=5, ipadx= 10, anchor="n")
main_antiduplicate_bouton = HoverButton(mainframe, font=("Arial", 15), text="Anti-Duplicate",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command=Anti_Duplicate)
main_antiduplicate_bouton.pack(side= "left", padx= 5, pady=5, ipadx= 30)
main_split_button = HoverButton(mainframe, font=("Arial", 15), text="Split",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command=None)
main_split_button.pack(side= "left", padx= 5, pady=5, ipadx= 19, anchor="n")
root.mainloop()
main_menu()
So here's my code allows you to use 3 tools:
"Split" / "Anti-Duplicate" / "Merge"
At the moment I'm working on the "Anti-Duplicate" so it's on this Frame() where the text should be displayed.
I've already done everything, even the button to open the file explorer, but for the moment the location of the file is only displayed in the cmd.
Thank you very much!
The location of the file does not show up because you created a new frame to hold the label fichier_dir inside OpenFile_AntiDuplicate() and you did not call any layout function on the frame, so the frame will not be shown.
Better create the label fichier_dir inside Anti_Duplicate() and pass it to OpenFile_AntiDuplicate() function:
def Anti_Duplicate():
...
fichier_dir = tk.Label(mainframe, bg='#1c2028', fg='white')
fichier_dir.place(relx=0.5, y=170, anchor='n')
open_button = HoverButton(mainframe, font=("Arial", 10), text="Open File..",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command = lambda: OpenFile_AntiDuplicate(fichier_dir))
...
And update OpenFile_AntiDuplicate(...):
def OpenFile_AntiDuplicate(fichier_dir):
global antiduplicate_file
antiduplicate_file = askopenfilename(initialdir="/",
filetypes =(("Text file", "*.txt"),("All files","*.*")),
title = "Open text file"
)
fichier_dir['text'] = antiduplicate_file
...