With my current code, it does not matter whether I click on "Input Folder" - Change or "JukeBox" change the result always gets displayed in "JukeBox" entry. This is incorrect, using class and self how can I change the code to display result from "Input Folder" - Change in "Input Folder" entry and the result from "Jukbox" - Change in "Jukebox" entry?
Also, how can I save the selected folders to a file so that it is there on app exit and re open?
My code:
import os
from tkinter import *
from tkinter import filedialog
inPut_dir = ''
jukeBox_dir = ''
def inPut():
opendir = filedialog.askdirectory(parent=root,initialdir="/",title='Input Folder')
inPut_dir = StringVar()
inPut_dir = os.path.abspath(opendir)
entry.delete(0, END)
entry.insert(0, inPut_dir)
def jukeBox():
opendir = filedialog.askdirectory(parent=root,initialdir="/",title='JukeBox')
jukeBox_dir = StringVar()
jukeBox_dir = os.path.abspath(opendir)
entry.delete(0, END)
entry.insert(0, jukeBox_dir)
root = Tk()
root.geometry("640x240")
root.title("Settings")
frametop = Frame(root)
framebottom = Frame(root)
frameright = Frame(framebottom)
text = Label(frametop, text="Input Folder").grid(row=5, column=2)
entry = Entry(frametop, width=50, textvariable=inPut_dir)
entry.grid(row=5,column=4,padx=2,pady=2,sticky='we',columnspan=20)
text = Label(frametop, text="JukeBox").grid(row=6, column=2)
entry = Entry(frametop, width=50, textvariable=jukeBox_dir)
entry.grid(row=6,column=4,padx=2,pady=2,sticky='we',columnspan=20)
ButtonA = Button(frametop, text="Change", command=inPut).grid(row=5, column=28)
ButtonB = Button(frametop, text="Change", command=jukeBox).grid(row=6, column=28)
ButtonC = Button(frameright, text="OK").grid(row=5, column=20, padx=10)
ButtonD = Button(frameright, text="Cancel").grid(row=5, column=15)
frametop.pack(side=TOP, fill=BOTH, expand=1)
framebottom.pack(side=BOTTOM, fill=BOTH, expand=1)
frameright.pack(side=RIGHT)
root.mainloop()
See attached image:enter image description here
Your code has both:
entry = Entry(frametop, width=50, textvariable=inPut_dir)
entry.grid(row=5,column=4,padx=2,pady=2,sticky='we',columnspan=20)
and
entry = Entry(frametop, width=50, textvariable=jukeBox_dir)
entry.grid(row=6,column=4,padx=2,pady=2,sticky='we',columnspan=20)
with jukeBox_dir/row 6 overriding inPut_dir/row 5
Therefore, in def input:
where you have:
entry.insert(0, inPut_dir)
You'll get the result in row 5 (jukebox_dir)
Related
I'm new to python and I'm wondering how to validate if label text exists. I'm getting an error:
Below's my full code. You can see the function validate at the bottom, and I'm figuring out how to make the label work in if else condition.
import openpyxl, os
import glob
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
class Root(Tk):
def __init__(self):
super(Root, self).__init__()
#Add a widget title
self.title("Automated filling up of form in iPage")
#Set widget width and height
self.minsize(300, 200)
#Display browse button
self.displayForm()
def doubleQuote(self, word):
return '"%s"' % word
def displayForm(self):
#Display label frame
self.labelFrame = ttk.LabelFrame(self, text = "Open Excel File")
self.labelFrame.grid(column=1, row=2, pady=5, sticky=NW)
#Create browse button
self.button = ttk.Button(self.labelFrame, text = "Browse a File",command = self.openFileDialog)
self.button.grid(column=1, row=1, padx=5, pady=5)
ttk.Label(self, text="Cell From:").grid(column=0, row=0, padx=5)
ttk.Label(self, text="Cell To:").grid(column=0, row=1, padx=5)
self.cf = StringVar()
self.ct = StringVar()
self.cellFrom = ttk.Entry(self, textvariable=self.cf)
self.cellTo = ttk.Entry(self, textvariable=self.ct)
self.cellFrom.grid(column=1, row=0, pady=5)
self.cellTo.grid(column=1, row=1, pady=5)
self.cf.trace("w",self.validate)
self.ct.trace("w",self.validate)
self.submitBtn = ttk.Button(self, text='Submit', command=self.validate)
self.submitBtn.grid(column=1, row=3, pady=5, sticky=NW)
def openFileDialog(self):
#Create a file dialog
self.filename = filedialog.askopenfilename(initialdir = "/", title = "Select A File", filetype =
[("Excel files", ".xlsx .xls")])
self.label = ttk.Label(self.labelFrame, text = "", textvariable=self.fl)
self.label.grid(column = 1, row = 2)
#Change label text to file directory
self.label.configure(text = self.filename)
self.label.trace("w",self.validate)
#Return tail of the path
self.trimmed = os.path.basename(self.filename)
#Pass tail variable
self.openSpreadsheet(self.trimmed)
def openSpreadsheet(self, tail):
#Open excel spreadsheet
self.wb = openpyxl.load_workbook(tail)
self.sheet = self.wb['Sheet1']
#Return data from excel spreadsheet
for rowOfCellObjects in self.sheet[self.cf.get():self.ct.get()]:
#Loop through data
for link in rowOfCellObjects:
#Remove www and firstlightplus.com text
self.cleanURL = link.value.replace("www.", " ").replace(".firstlightplus.com", "")
print(self.cleanURL)
def validate(self, *args):
#Retrieve the value from the entry and store it to a variable
if self.cf.get() and self.ct.get() and self.label["text"]:
print("normal")
self.submitBtn.config(state='normal')
else:
print("disabled")
self.submitBtn.config(state='disabled')
root = Root()
root.mainloop()
I believe the problem is the validate function can be called before the openFileDialog function. This way, the label attribute is being accessed before it has been created.
A simple solution would be initialize the attribute in the displayForm function:
def displayForm(self):
#Display label frame
self.labelFrame = ttk.LabelFrame(self, text = "Open Excel File")
self.labelFrame.grid(column=1, row=2, pady=5, sticky=NW)
self.label = None
# ... Rest of the code
And then, before accessing the attribute, test if it exists:
def validate(self, *args):
#Retrieve the value from the entry and store it to a variable
if self.cf.get() and self.ct.get() and self.label and self.label["text"]:
print("normal")
self.submitBtn.config(state='normal')
else:
print("disabled")
self.submitBtn.config(state='disabled')
I cannot get my code to pass the pop up text entry to a global variable i am also attempting to set this global variable as the default text in the entry field in all future instances.
Pop up -> Enter Filepath -> accept&close -> Re-open shows last filepath present as default -> if changed new filepath entry becomes default in future.
import tkinter as tk
from tkinter import ttk
from tkinter import *
master = tk.Tk()
Var1 = StringVar()
Filepath_Var = None
def A_Connect():
root = Tk()
root.title("Entry Field")
def entry_field():
global Filepath_Var
Filepath_Var = Var1.get()
tk.Label(root, text="filepath: ").grid(row=0)
e1 = tk.Entry(root, textvariable=Var1)
tk.Label(root, text="Item Number: ").grid(row=1)
e2 = tk.Entry(root)
#e1.insert(0, r"C:\Users\zxy\ghj\iugf\Bea\something.xlsx")
e1.insert(0, Var1.get())
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
Button(root, text = 'Accept', command = entry_field).grid(row=3, column=1,
sticky=W, pady=4)
root.mainloop()
note = ttk.Notebook(master)
tab1 = tk.Frame(note)
canvas7 = Canvas(tab1, width=520, height=350)
canvas7.pack()
A_Button = tk.Button(tab1, text="A",
width=12, height=3,command=A_Connect, anchor = 'w')
A_Button_Window = canvas7.create_window(20, 120, anchor = 'sw',
window = A_Button)
note.add(tab1, text = " Main ")
note.pack()
master.mainloop()
As a follow up to your earlier question, I encapsulated an example of the (bare bones) desired behavior in two classes:
The main App consists of a button that launches an entry popup; upon filling the fields and accepting, the value in the entry is provided to the App, and the popup closed.
The value entered is stored by the App, and used to populate the entry field of the entry fields in successive popups.
You will probably want to add confirmations and verifications before changing the defaults, and closing the popup, but here, you have the basic skeleton to attach this to.
import tkinter as tk
class PopUpEntry(tk.Toplevel):
def __init__(self, master, default_value=None):
self.master = master
super().__init__(self.master)
if default_value is None:
self.default_entry = 'C:*****\somthing.xlsx'
else:
self.default_entry = default_value
self.title("Entry Field")
tk.Label(self, text="Filepath: ").pack()
self.e1 = tk.Entry(self)
self.e1.insert(0, self.default_entry)
self.e1.pack()
tk.Button(self, text = 'Accept', command=self.entry_field).pack()
def entry_field(self):
self.default_entry = self.e1.get()
self.master.provide_entry_value(self.default_entry)
self.destroy()
class App(tk.Tk):
def __init__(self):
super().__init__()
self.pop_entry = tk.Button(self, text='launch entry', command=self.launch_entry)
self.pop_entry.pack()
self.default_entry_value = None
self.mainloop()
def launch_entry(self):
PopUpEntry(self, self.default_entry_value)
def provide_entry_value(self, value):
self.default_entry_value = value
print(self.default_entry_value)
App()
I am a newbie in Python. I want to create a program with Tkinter that takes the entry from the entry "box" and then compares each character of it with the charset and finally pops up a messagebox that shows the phrase. I have almost complete it but I can not make this line work:
info_menu.add_command(label="About",
command=messagebox.showwarning(message="Creator: GakPower\nVersion: 1.0.0\nCreated at 1/5/2017")
Full code:
from tkinter import ttk
from tkinter import *
from tkinter import messagebox
import string as s
class Bruteforcer:
def output(self, result):
self.result = result
if result == "":
messagebox.showwarning(title="Enter a Phrase",
message="Please enter a Phrase!")
else:
messagebox.showinfo(title="Phrase Found!",
message=("The process completed Successfully!\n The Phrase Found!!!!\n", result))
def submit_button_pressed(self):
entry_val = self.entry_value.get()
charset = list(s.ascii_letters + "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψω" + s.digits + s.punctuation)
result = ""
x = 0
while x <= len(entry_val)-1:
echar = entry_val[x]
for char in charset:
if char == echar:
result += echar
x += 1
break
return self.output(result)
def __init__(self, root):
self.entry_value = StringVar(root, "")
self.the_menu = Menu(root)
info_menu = Menu(self.the_menu, tearoff=0)
**info_menu.add_command(label="About",
command=messagebox.showwarning(message="Creator: GakPower\nVersion: 1.0.0\nCreated at 1/5/2017")**
)
info_menu.add_separator()
info_menu.add_command(label="Quit", command=root.quit)
self.the_menu.add_cascade(label="Info", menu=info_menu)
root.config(menu=self.the_menu)
text_fond = StringVar()
text_fond.set("Times")
root.title("Graphical Bruteforcer")
root.geometry("500x500")
root.resizable(width=False, height=False)
style = ttk.Style()
style.configure("TButton",
foreground="red",
fond="Times 20",
padding=10)
style.configure("TEntry",
foreground="red",
fond="Times 20",
padding=10)
style.configure("TLabel",
foreground="red",
fond="Times 35 Bold")
# ---------- Entry -----------
self.entry_value = ttk.Entry(root,
textvariable=self.entry_value, width=25, state="normal")
self.entry_value.grid(row=1, columnspan=2)
# ---------- Label ----------
self.secret_label = ttk.Label(root,
text="The Secret Phrase").grid(row=0, column=0)
# ---------- Button ---------
self.button_submit = ttk.Button(root,
text="Submit", command=self.submit_button_pressed)
self.button_submit.grid(row=1, column=2)
root = Tk()
brute = Bruteforcer(root)
root.mainloop()
As furas said in the comments, command= expects a function. So you should replace
info_menu.add_command(label="About",
command=messagebox.showwarning(message="Creator: GakPower\nVersion: 1.0.0\nCreated at 1/5/2017"))
by something like
def show_about():
''' show the about messagebox '''
messagebox.showwarning(message="Creator: GakPower\nVersion: 1.0.0\nCreated at 1/5/2017")
info_menu.add_command(label="About", command=show_about)
below is my code for creating a tool that takes a file path, stores the value, and then opens the specific file path selected by the user.
Currently, I'm looking to take the user entry mypathEntry that is stored in the mypathList listbox after clicking the Save button and add a command to it. The command will open that selected file path. My current code returns an error message regarding mypathList.add_command(command=Open) stating that Listbox instance has no attribute 'add_command'.
What is the syntax for adding a command to a listbox item?
from Tkinter import *
import os
root = Tk()
def Save():
fp = mypathEntry.get()
scribe = open('filepath.txt', 'w')
scribe.write(fp)
mypathEntry.delete(0, 'end')
mypathList.insert(1, fp)
def Open():
path = fp
menu = Menu(root)
##root.config(menu=menu)
##subMenu = Menu(menu)
##menu.add_cascade(label="Filepaths", menu=subMenu)
##subMenu.add_command(command=Save)
mypathLabel = Label(root, text="Copy and Paste your filepath here:")
mypathEntry = Entry(root, bg="black", fg="white", relief=SUNKEN)
mypathSaveButton = Button(root, text="Save Path", bg="black", fg="white", command=Save)
mypathList = Listbox(root, bg="black", fg="white")
mypathList.add_command(command=Open)
mypathLabel.pack()
mypathEntry.pack()
mypathSaveButton.pack()
mypathList.pack()
root.mainloop()
According to this,
http://effbot.org/tkinterbook/listbox.htm
The listbox item does not have a command option. So what you need to do instead is to bind an event to it. Here is a complete working example.
from tkinter import *
import os
root = Tk()
class MainGui:
def __init__(self, master):
self.mypathLabel = Label(master, text="Copy and Paste your filepath here:")
self.mypathEntry = Entry(master, bg="black", fg="white", relief=SUNKEN)
self.mypathSaveButton = Button(master, text="Save Path", bg="black", fg="white", command=self.save_path)
self.mypathList = Listbox(master, bg="black", fg="white")
self.mypathLabel.pack()
self.mypathEntry.pack()
self.mypathSaveButton.pack()
self.mypathList.pack()
self.mypathList.bind("<Double-Button-1>", self.open_path)
def save_path(self):
fp = self.mypathEntry.get()
self.mypathEntry.delete(0, 'end')
self.mypathList.insert(1, fp)
def open_path(self, event):
list_item = self.mypathList.curselection()
fp = self.mypathList.get(list_item[0])
print(fp)
try:
with open(fp, 'r') as result:
print(result.read())
except Exception as e:
print(e)
MainGui(root)
root.mainloop()
Someone please help me figure this out.
I have the following problem in Tkinter Python. The problem is that the text is overlaying with the previous text. and/or is copying below that.
I've tried to use label.config(root).pack() instead of Label(root, text="").pack()
This kinda solves the problem it starts to write over the previous text but there are 2 problems with this.
1: the text old text/Entrys all still there, it just overlays.
2: this only works with label.config, and I would also like this to work with buttons and Entrys(textbox)
I've also tried .pack_forget() and .destroy() but unfortunately it did nothing.
CODE
from tkinter import *
import pickle
import time
import os
def new_profile():
global Var1, Var2
var1 = StringVar()
var2 = StringVar()
Label(root, text="Create a new profile").pack()
Label(root, text="User Name").pack()
Entry(root, textvariable=var1).pack()
Label(root, text="Password").pack()
Entry(root, textvariable=var2).pack()
Button(root, text="Create", command=create_profile).pack()
Var1, Var2 = var1, var2
return
def create_profile():
text1 = Var1.get()
text2 = Var2.get()
print(text1)
dict = {}
dict['Name'] = text1
dict['Password'] = text2
pickle.dump(dict, open("test.txt", "wb"))
dict1 = pickle.load(open("test.txt", "rb"))
if dict1['Name'] == text1 and dict1['Password'] == text2:
Label(root, text="").pack()
Label(root, text="Profile creation successful", ).pack()
Label(root, text="Name:" + " " + text1).pack()
Label(root, text="Password:" + " " + text2).pack()
else:
Label(root, text="Something went wrong while creating your profile.", ).pack()
return
def load_profile():
select = "Load profile.."
label.config(text=select)
return
root = Tk()
root.geometry("500x400+300+300")
root.title("client")
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="New Profile", command=new_profile)
filemenu.add_command(label="Load Profile", command=load_profile)
menubar.add_cascade(label="Profile Options", menu=filemenu)
root.config(menu=menubar)
label = Label(root)
label.pack()
root.mainloop()
create a array such as
on_screen = []
at the start then name your widgets and and add them to the array
password_label = Label(root, text="Password").pack()
password = Entry(root, textvariable=var2).pack()
on_screen.append(password)
on_screen.append(password_label)
then use a for loop to destroy all the widgets in the array
for w in on_screen:
w.destroy()