tkinter user input widget to xlsx - python-3.x

How do I write user input from tkinter entry widget to xlsx?
Should I be using a different module?
from tkinter import *
import xlsxwriter
def output():
c = Toplevel(root)
c.title =("Main")
c.geometry =('')
e= Entry(c, width=20).grid(row=0, column=1, sticky=W, padx=10)
l=Label(c, text="Current Value").grid(row = 0, column=0, sticky=W, padx=10)
e2 = Entry(c, width=20).grid(row=1, column=1, sticky=W, padx=10)
l2= Label(c, text="New Value").grid(row = 1, column=0, sticky=W, padx=10)
b=Button(c, text="Submit",command= write_to_xlsx).grid(row= 1, column=2, sticky=E, padx=10)
def write_to_xlsx():
workbook =xlsxwriter.Workbook('tkintertest18.xlsx')
worksheet = workbook.add_worksheet()
worksheet.write_string('C1', 'e2.get()')
workbook.close()
root = Tk()
root.title("Main Menu")
root.geometry('400x400+230+130')
Button(root, text="1", command=output).grid(row =0, column= 2)
root.mainloop()

You should almost always use a class when tkinter is involved. So here is a working prototype of your code above. There were multiple problems. One is that when you slap grid next to your widgets instead of putting them on a new line, grid returns None, not the object. Implementing the app as a class enables the other functions to access the GUI components (in this case self.e2). Another error was you had single-quoted the 'e2.get()' call, which is technically a string. So removing the quotes fixes that. There may have been other things...
import xlsxwriter
class XLwriter:
def __init__(self):
c = Toplevel(root)
c.title =("Main")
c.geometry =('')
self.e= Entry(c, width=20).grid(row=0, column=1, sticky=W, padx=10)
self.l=Label(c, text="Current Value").grid(row = 0, column=0, sticky=W, padx=10)
self.e2 = Entry(c, width=20)
self.e2.grid(row=1, column=1, sticky=W, padx=10)
self.l2= Label(c, text="New Value").grid(row = 1, column=0, sticky=W, padx=10)
self.b=Button(c, text="Submit",command=self.write_to_xlsx).grid(row= 1, column=2, sticky=E, padx=10)
def write_to_xlsx(self):
workbook =xlsxwriter.Workbook('tkintertest18.xlsx')
worksheet = workbook.add_worksheet()
worksheet.write_string('C1', self.e2.get())
workbook.close()
root = Tk()
root.title("Main Menu")
root.geometry('400x400+230+130')
app = XLwriter()
#Button(root, text="1", command=output).grid(row =0, column= 2)
root.mainloop()

Seeing that Ron already provided you with a class to perform this task I will respond with the non-class method of doing this to more closely reflect the current code you have.
Keep in mind that with xlsxwriter there is not a way to read from the spreadsheet so for the entry field you have that is labeled as "Current Value" you will need to use a different excel library to fill that field with data from the spreadsheet.
Make sure if you are going to interact with a widget that you do not use the geometry manager directly with the creation of the widget. This will return None to anything trying to interact with it. Instead on the next line after you have created the widget you can use the widget variable name and then your geometry manager of choice(grid(), pack(), place()). This will allow us to interact with the widget without the issue of None being returned by the geometry manager.
In order for you to be able to interact with e2 outside of the output() function you will need to assign e2 to the global namespace. You can do this by simply adding global e2 inside your output() function.
Note: The use of global is best avoided whenever possible this is one compelling reason to use a more Object Oriented Programing method (class) as the use of global is not needed when using class attributes.
from tkinter import *
import xlsxwriter
root = Tk()
root.title("Main Menu")
#root.geometry('400x400+230+130')
def output():
global e2
c = Toplevel(root)
c.title = ("Main")
e = Entry(c, width = 20)
e.grid(row = 0, column = 1, sticky = W, padx = 10)
l = Label(c, text = "Current Value")
l.grid(row = 0, column = 0, sticky = W, padx = 10)
e2 = Entry(c, width=20)
e2.grid(row = 1, column = 1, sticky = W, padx = 10)
l2 = Label(c, text = "New Value")
l2.grid(row = 1, column = 0, sticky = W, padx = 10)
b = Button(c, text = "Submit",command = write_to_xlsx)
b.grid(row = 1, column = 2, sticky = E, padx = 10)
def write_to_xlsx():
workbook = xlsxwriter.Workbook('tkintertest18.xlsx')
worksheet = workbook.add_worksheet()
worksheet.write_string('C1', e2.get())
workbook.close()
btn = Button(root, text = "1", command = output)
btn.grid(row = 0, column = 2)
root.mainloop()

Related

tkinter scrollbar with grid, it doesn't get linked

I'm studying GUI, so please understand my poor codes below.
I was trying to make a program which gets game-character's information. So if you press the 'search' button, the list would be shown below. But... it only shows about 11 names due to the window size. So i wanted to put a scrollbar for that area, but I just don't know how to link the scroll bar to control the area. I meant, the scroll bar itself has created, and it does scroll itself, but it doesn't scroll the window I wanted. I must have linked it wrong but... not sure.
Below is the minimized example code, but it's still quite long and crude. Sorry for that again.
If anyone can enlighten me, it would be really great help for this and my future works as well.
import tkinter as tk
import requests
from bs4 import BeautifulSoup
import webbrowser
import time
global var_dict, input_id, output
var_dict = {}
def enter_call_back(event=None):
output.grid(column = 0, row = 2, columnspan = 5 , sticky='w')
output.insert(tk.END,"Text_Something")
output.update()
search_chr()
def open_browse(url_list):
for url in url_list:
time.sleep(0.3)
webbrowser.open(url)
def search_inven(ch_id):
if ch_id == "ch1" or ch_id == "ch13" or ch_id == "ch15" :
num = 5
url_list = ["something.url","something2.url"]
self_count = 1
else:
num = 0
url_list = []
self_count = 0
masterset = []
masterset.append(num)
masterset.append(url_list)
masterset.append(self_count)
return masterset
def search_chr():
global var_dict, output
for things in var_dict.keys():
var_dict[things].destroy()
chr_list = ["ch1","ch2","ch3","ch4","ch5","ch6","ch7","ch8","ch9","ch9","ch10","ch11","ch12","ch13","ch14","ch15"]
output.insert(tk.END," Done! \n\n")
var_dict = {}
num = -1
for ch in chr_list:
num += 1
var_dict["output%s" %num] = tk.Entry(frame_buttons, width = 125)
result = search_inven(ch)
if result[0] == 0:
var_dict["output"+str(num)].insert(0, "Clean "+ch+"\n")
var_dict["output"+str(num)].grid(column = 0, row = num, sticky='w', padx=5, pady=5)
else:
url_list = result[1]
var_dict["o-button%s" %num] = tk.Button(frame_buttons, command=lambda url_list = url_list : open_browse(url_list))
var_dict["o-button"+str(num)].grid(column = 1, row = num, sticky='e')
var_dict["o-button"+str(num)].config(text="URL")
var_dict["output"+str(num)].insert(0, "Not Clean "+str(result[0])+" Self : "+str(result[2])+" Ch_id : "+ch+")\n")
var_dict["output"+str(num)].grid(column = 0, row = num, sticky='w', padx=5, pady=5)
vsb = tk.Scrollbar(frame_canvas, orient="vertical")
vsb.grid(row=0, column=1, sticky='ns')
vsb.config(command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set)
frame_canvas.config(height = 300)
canvas.config(scrollregion=canvas.bbox("all"))
root = tk.Tk()
root.geometry("760x710")
root.resizable(width=False, height=False)
root.title("Minimum v.1.2")
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
frame_main = tk.Frame(root, bg="gray")
frame_main.grid(sticky='news')
intro = tk.Text(frame_main, height = 17, bg="#E3D5F3")
intro.option_add("*Font", "명조 10")
intro.insert(tk.CURRENT,"Text_something")
intro.config(state='disabled')
intro.grid(row=0, column=0, pady=(5, 0), columnspan = 5, sticky='nw')
input_id = tk.Entry(frame_main, width = 35)
input_id.option_add("*Font","명조 10")
input_id.insert(0,"Ch_name")
input_id.grid(row=1, column=0, pady=(5, 0), sticky='w')
search_btn = tk.Button(frame_main)
search_btn.config(text="Search")
search_btn.option_add("*Font","명조 10")
search_btn.config(width=5,height=1)
search_btn.grid(row = 1, column = 0, pady=(5, 0), sticky='e')
output = tk.Text(frame_main, height = 10)
output.option_add("*Font","명조 10")
output.grid(row = 2, column = 0,pady=(5,0),sticky='nw')
frame_canvas = tk.Frame(frame_main, width = 565)
frame_canvas.grid(row=3, column=0, pady=(5, 0), columnspan = 3 ,sticky='nw')
frame_canvas.grid_rowconfigure(0, weight=1)
frame_canvas.grid_columnconfigure(0, weight=1)
frame_canvas.grid_propagate(False)
canvas = tk.Canvas(frame_canvas, bg="gray", height=500,scrollregion=(0,0,500,1800))
canvas.grid(row=0, column=0, sticky="news")
frame_buttons = tk.Frame(canvas, bg="gray")
frame_buttons.grid(row = 0, column = 0,sticky='e')
root.bind('<Return>',enter_call_back)
search_btn.config(command = enter_call_back)
root.mainloop()
First, using grid() to put frame_buttons into the canvas will not affect the scrollregion of the canvas. Use canvas.create_window() instead.
Second, it is better to bind <Configure> event on frame_buttons and update canvas' scrollregion inside the bind callback. Then adding widgets to frame_buttons will automatically update the scrollregion.
Also note that you have created new scrollbar and put it at same position whenever search_chr() is executed. Better create the scrollbar only once outside the function.

How to reproduce class within tkinter

I built a little Synchronizer GUI program, using tkinter. I recently tried adding a +-Button, which reproduces the filebrowsing buttons and entry fields, so I can sync more than 2 directories. (I.e. personally, I have my Documents as well as Pictures backed up on a USB drive that I want to keep updated, but I dont want to copy my whole /home directory.)
I have run into two issues. The first issue is with the positioning of the plus Button: I have initialized the rowcount to zero, so everytime I click the +-Button, the new line of Buttons/fields is actually on a new line. sadly, this does not work for the plus button, that is defined outside the fuction, but shouldn't self.rowcount += 1 adjust rowcount for the whole class?
Secondly, I am not sure how to handle self.sourcefile and self.targetfile: When I select a new folder, it replaces the previous input, which is not the idea.
I would really appreciate any help!
from tkinter import *
from tkinter import filedialog
class Application():
def __init__(self):
self.root = Tk()
self.rowcount = 0
self.sourcefile = ""
self.targetfile = ""
self.sourceDirectory = Entry(self.root, width=10)
self.targetDirectory = Entry(self.root, width=10)
self.sourceDirectory.insert(0, "Source")
self.targetDirectory.insert(1, "Target")
selectSource = Button(self.root, text = "browse source", command=self.select_source, height=15, width=15)
selectTarget = Button(self.root, text = "browse target", command=self.select_target, height=15, width=15)
plusButton = Button(self.root, text = "+", command=self.create_new)
self.sourceDirectory.grid(row=0, column=0)
self.targetDirectory.grid(row=0, column=5)
selectSource.grid(row=0, column=1)
selectTarget.grid(row=0, column=10)
plusButton.grid(row=self.rowcount + 1, column=10)
self.root.mainloop()
def create_new(self):
self.rowcount += 1
print(self.rowcount)
self.sourceDirectory = Entry(self.root, width=10)
self.targetDirectory = Entry(self.root, width=10)
self.sourceDirectory.insert(0, "Source")
self.targetDirectory.insert(1, "Target")
selectSource = Button(self.root, image=self.browsericon, command=self.select_source, height=15, width=15)
selectTarget = Button(self.root, image=self.browsericon, command=self.select_target, height=15, width=15)
self.sourceDirectory.grid(row=self.rowcount, column=0)
self.targetDirectory.grid(row=self.rowcount, column=5)
selectSource.grid(row=self.rowcount, column=1)
selectTarget.grid(row=self.rowcount, column=10)
def select_source(self):
source = filedialog.askdirectory(title="Select Source")
self.sourceDirectory.delete(0, END)
self.sourceDirectory.insert(0, source)
self.sourcefile = source
def select_target(self):
target = filedialog.askdirectory(title="Select Target")
self.targetDirectory.delete(0, END)
self.targetDirectory.insert(1, target)
self.targetfile = target
Application()
shouldn't self.rowcount += 1 adjust rowcount for the whole class?
Yes, and it does in your code. However, changing the variable won't change the location of a widget that used that variable in a grid command.
My advice is to put the rows in one frame and the buttons in another. That way you don't have to keep adjusting the location of the buttons. For example:
self.row_frame = Frame(self.root)
self.button_frame = Frame(self.root)
self.button_frame.pack(side="bottom", fill="x")
self.row_frame.pack(side="top", fill="both", expand=True
Also, if the "+" button creates a new row, it shouldn't be duplicating code. You need to have a single function for adding a row. Since you already have a function to do that, you can call that function in __init__.
Putting it all together it looks something like this:
class Application():
def __init__(self):
self.root = Tk()
self.root.title("File Synchronizer")
self.rowcount = 0
self.sourcefile = ""
self.targetfile = ""
self.row_frame = Frame(self.root)
self.button_frame = Frame(self.root)
self.button_frame.pack(side="bottom", fill="x")
self.row_frame.pack(side="top", fill="both", expand=True)
startSync = Button(self.button_frame, text="Start", command=self.synchronize)
plusButton = Button(self.button_frame, text = "+", command=self.create_new)
startSync.grid(row=1, column=2)
plusButton.grid(row=0, column=10)
self.create_new()
self.root.mainloop()
def create_new(self):
self.rowcount += 1
self.sourceDirectory = Entry(self.row_frame, width=10)
self.targetDirectory = Entry(self.row_frame, width=10)
self.sourceDirectory.insert(0, "Source")
self.targetDirectory.insert(1, "Target")
selectSource = Button(self.row_frame, text = "browse source", command=self.select_source)
selectTarget = Button(self.row_frame, text = "browse source", command=self.select_target)
self.sourceDirectory.grid(row=self.rowcount, column=0)
self.targetDirectory.grid(row=self.rowcount, column=5)
selectSource.grid(row=self.rowcount, column=1)
selectTarget.grid(row=self.rowcount, column=10)
This doesn't put the "plus" and "Start" button in exactly the same place, but that's just because it's somewhat irrelevant to the answer. You can use whatever options you want to place it in the button frame. Since the two frames are independent, you can adjust rows, columns, and weights in one without affecting the other. Or, you can use pack in one frame and grid in another.
The other problem with your code is that self.sourceDirectory and self.targetDirectory can only hold one value so it will always refer to the last widgets that were created.
Since you are creating multiple source and target widgets, you need to save them in a list.
For example, start by adding an empty list to your application in the __init__ method:
self.sources = []
self.targets = []
Then, when you add a new row, append it to the list:
source_entry = Entry(self.row_frame, width=10)
target_entry = Entry(self.row_frame, width=10)
self.sources.append(source_entry)
self.targets.append(target_entry)
You can then iterate over these two lists to process all source and target values.
You will also have to modify the callback for the browse functions to accept an index so that the button knows which entry to update.

Scrollbar for Dynamically Created Widgets - Python Tkinter [duplicate]

This question already has answers here:
Adding a scrollbar to a group of widgets in Tkinter
(3 answers)
Closed 3 years ago.
I have a GUI that dynamically generates widgets based on the user selected number of systems:
GUI
These widgets are generated using a Callback function like the below sample of code:
class Window():
def __init__(self, master):
master.title('Production Analysis Tool')
# callback function to create entry boxes based on number of systems
self.L0 = Label(root, text="Equipment Parameters:", font = ('TKDefaultFont', 9, 'bold'))
self.L0.grid(row=3,column=0, sticky=W)
inverter_file = r'F:\CORP\PROJECTS\07599-A_Solar Development\Screening\_Production Analysis Tool\User Inputs\Inverter_Data.csv'
module_file = r'F:\CORP\PROJECTS\07599-A_Solar Development\Screening\_Production Analysis Tool\User Inputs\Module_Data.csv'
def update_scroll_region(event):
canvas.configure(scrollregion=canvas.bbox("all"))
def callback(*args):
dynamic_widgets = Frame(canvas)
canvas.create_window(0,0, anchor='nw', window = dynamic_widgets)
self.system_size = int(self.system_size_raw.get())
# Inverter Type
self.Lblank = Label(dynamic_widgets, text = "").grid(row=8, column=1, sticky=W)
self.L3 = Label(dynamic_widgets, text = "Inverter Type")
self.L3.grid(row=9, column=1, sticky=W)
global inverter_types # declare array as global parameter so it can be accessed outside function
inverter_types = []
for i in range(self.system_size):
inverter_list = get_inverter_list(inverter_file)
inverter_list = ["Select"] + inverter_list
self.inverter_types_raw = StringVar()
self.L3a = Label(dynamic_widgets, text = "System {}".format(i+1), font = ('Calibri', 10,'italic'))
self.L3a.grid(row=10+i, column=1, sticky=E)
self.widget = OptionMenu(dynamic_widgets, self.inverter_types_raw, *inverter_list, command = get_values_0)
self.widget.grid(row=10+i, column=2,sticky=EW)
inverter_types.append(self.widget)
dynamic_widgets.bind("<Configure>", update_scroll_region)
global inv_type
inv_type = []
def get_values_0(value):
inv_type.append(value)
button = tk.Button(root, text = "Store Values", font=('Calibri', 10,'italic'), bg = "SlateGray3",command = lambda:[gget_values_0()])
button.grid(row = 61, column = 2, columnspan=8, sticky = 'nesw')
# System Type
self.L1 = Label(root, text = "System Type")
self.L1.grid(row=4, column=1, sticky=W)
self.sys_type_raw = StringVar(root)
types = ['Select', 'Central Inverter', 'String Inverters']
self.popupMenu6 = OptionMenu(root, self.sys_type_raw, *types)
self.popupMenu6.grid(row=4, column=2, sticky=EW)
# Number of Systems
self.L2 = Label(root, text = "Number of Systems")
self.L2.grid(row=6, column=1, sticky=W)
self.system_size_raw = IntVar(root)
choices = list(range(1,50))
self.popupMenu2 = OptionMenu(root, self.system_size_raw, *choices)
self.popupMenu2.grid(row=6, column=2, sticky=EW)
self.system_size_raw.trace("w", callback)
vsb = Scrollbar(root, orient="vertical")
vsb.grid(row=8, column=6, sticky = 'ns')
canvas = Canvas(root, width = 600, height = 200)
vsb.config(command = canvas.yview)
canvas.configure(yscrollcommand=vsb.set)
canvas.grid(row=8,column=0)
# SITE ORIENTATION
self.L12 = Label(root, text="Site Orientation:", font = ('TKDefaultFont', 9, 'bold'))
self.L12.grid(row=66, column=0, sticky=W)
self.L13 = Label(root, text = "Module Tilt Angle (degrees)")
self.L13.grid(row=67, column=1, sticky=W)
self.modtilt_raw = Entry(master)
self.modtilt_raw.grid(row=67, column=2, sticky=EW)
self.L14 = Label(root, text = "Array Azimuth (degrees)")
self.L14.grid(row=68, column=1, sticky=W)
self.arraytilt_raw = Entry(master)
self.arraytilt_raw.grid(row=68, column=2, sticky=EW)
# SUBMIT INFORMATION
self.L27 = Label(root, text=" ").grid(row=84,column=1) # Add row of space
self.cbutton = tk.Button(root, text="SUBMIT",command = self.store_user_inputs, bg = "SlateGray3")
self.cbutton.grid(row=85, column = 0, columnspan=8, sticky = 'ew')
# STORE USER INPUT
def store_user_inputs(self):
self.system_size = np.float(self.system_size_raw.get())
# save all inputs as global parameters so they can be accessed as variables outside of GUI
global params
params = [self.system_type]
root = Tk()
root.configure()
window = Window(root)
root.mainloop()
I would like to place the dynamically generated widgets (Inverter Type, Modules per String, Strings per Inverter, Inverters per System, Module Type, and Max Current per System) into a scrollable frame.
I can post more code if needed.
A scrollable frame can be created by creating a Frame widget on a Canvas. An example is as follows:
vsb = Scrollbar(root, orient = VERTICAL)
vsb.pack(fill=Y, side = RIGHT, expand = FALSE)
canvas = Canvas(root, yscrollcommand=vsb.set)
canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
vsb.config(command = canvas.yview)
canvas.config(scrollregion = canvas.bbox("all"))
InverterType = Frame(canvas)
canvas.create_window(0, 0, anchor = NW, window = InverterType)
Now make sure to add all the widgets created in the callback function to this InverterType frame.
(TIP - replace root with InverterType)

tkinter frame not working properly

Can anyone help me why columnspan not having any effect in this code:
import tkinter as tk
root = tk.Tk()
frametop = tk.Frame(root).grid(row = 0, column = 0, columnspan = 2)
labeltest1 = tk.Label(frametop, text="A").grid(row = 0, column = 0)
labeltest2 = tk.Label(frametop, text="B").grid(row = 0, column = 1)
labeltest3 = tk.Label(frametop, text="C").grid(row = 0, column = 2)
framebottom = tk.Frame(root).grid(row = 1, column = 0)
labeltest4 = tk.Label(framebottom, text="Hello World").grid(row = 1, column = 0)
labeltest5 = tk.Label(framebottom, text="Hello World").grid(row = 1, column = 1)
labeltest6 = tk.Label(framebottom, text="Hello World").grid(row = 1, column = 2)
root.mainloop()
labeltest1, labeltest2, labeltest3 are being distributed in column similar to the widgets of framebottom. What I wanted is a grid of 3 columns inside a frame with a columnspan = 2 with the same row.
Something similar to this:
|| A | B | C ||
| Hello World | Hello World | Hello World |
The way your code is organized, the Frames have no effect; when you grid on the same line as the widget creation, None gets returned and stored in the variables you are using for the Frames, and Label. A consequence is that the labels are inserted directly into root.
The following does the same, with a placement of the labels per your request.
import tkinter as tk
root = tk.Tk()
tk.Label(root, text="A").grid(row=0, column=0, columnspan=2)
tk.Label(root, text="B").grid(row=0, column=2, columnspan=2)
tk.Label(root, text="C").grid(row=0, column=4, columnspan=2)
tk.Label(root, text="Hello World").grid(row=1, column=0, columnspan=3)
tk.Label(root, text="Hello World").grid(row=1, column=3, columnspan=3)
tk.Label(root, text="Hello World").grid(row=1, column=6, columnspan=3)
root.mainloop()
GUI appearance (osX):

for i in -loop with Entry widget

Trying to get hand of tkinter, widgets and neighboring areas.
Keep getting an error - and after hours of googling, not answers pop up.
For some reason this loop shows all of the filenames in the entry-line - rather than one at a time... - what am I doing wrong ?
Thanks for helping out !
__author__ = 'Orphan Black'
import os
import sys
from tkinter import *
from tkinter.scrolledtext import *
import time
class PermFrame(Frame):
def __init__ (self, master):
super(PermFrame, self).__init__(master)
self.grid()
self.create_widgets()
self.createLable()
menu = Menu()
self.master.config(menu=menu)
file = Menu(menu)
file.add_command(label="Settings", command=self.setting_menu)
file.add_command(label="Exit", command=self.client_exit)
menu.add_cascade(label="File", menu=file)
about = Menu(menu)
about.add_command(label="Info")
menu.add_cascade(label="About", menu=about)
self.enpath_label = Label(self, text = "Enter path: ")
self.enpath_label.grid(row = 2, column = 2, sticky = W, padx=5, pady=5)
self.path_ent = Entry(self, width=52)
self.path_ent.grid(row = 2, column = 3, sticky = W, padx=5, pady=5)
self.sub_bttn = Button(self, text = "Check", command = self.submit_path)
self.sub_bttn.grid(row = 2, column = 4, sticky = W, padx=5, pady=5)
self.run_bttn = Button(self, text = "Run", command = self.run_prg)
self.run_bttn.grid(row = 2, column = 5, sticky = W, padx=5, pady=5)
self.orgfn_label = Label(self, text = "Original name: ")
self.orgfn_label.grid(row = 4, column = 2, sticky = W, padx=5, pady=5)
self.org_filename = Text(self, width=37, height = 1, wrap = WORD)
self.org_filename.grid(row=4, column = 3, columnspan = 5, sticky = W, padx=5, pady=5)
self.newfn_label = Label(self, text = "New name: ")
self.newfn_label.grid(row = 5, column = 2, sticky = W, padx=5, pady=5)
self.new_filename = Text(self, width=37, height = 1, wrap = WORD)
self.new_filename.grid(row=5, column = 3, columnspan = 5, sticky = W, padx=5, pady=5)
self.constxt_label = Label(self, text = "Console ")
self.constxt_label.grid(row = 6, column = 2, sticky = W, padx=5, pady=0)
self.console_txt = ScrolledText(self, width=71, height = 5, wrap = WORD)
self.console_txt.grid(row=7, column = 2, columnspan = 4, sticky = W, padx=5, pady=0)
def submit_path(self):
# console = console
time_date = time.strftime("%H:%M:%S")
contents = self.path_ent.get()
message = ("\n{}: Trying {}...".format(time_date, contents))
self.console_txt.insert(END, message)
try:
os.chdir(contents)
msgok = ("\n{}: The path {}, is valid".format(time_date, contents))
prg_start = ("\n{}: Program starting...".format(time_date, contents))
self.console_txt.insert(END, msgok)
except (ValueError, RuntimeError, TypeError, NameError, FileNotFoundError):
notok_mssg= ("\n{}: The path you entered is not valid...Enter a new path".format(time_date))
self.console_txt.insert(END,notok_mssg,)
def run_prg(self):
os.listdir(self.path_ent.get())
for file in os.listdir(self.path_ent.get()):
#print(file)
self.org_filename.insert(END,(file))
It seems like you want your entry widget to display the contents of os.listdir one at a time as you iterate over it changing the entry widgets value upon each iteration.
But, as you're iterating you keep inserting things into the entry widget at the last index in the Entry widget. You never delete the Entry widget's contents so you just see this is one big mesh of text.
Sticking with the Entry widget... you can do this:
self.org_filename.delete(0, END) #Could also use "end" instead of END
#insert new text
If all you want is this updating text behavior, then you should really just use a label. With a label it's easier.
some_label['text'] = new_filename
Additional notes:
Don't override keywords
You should use a name other than file in your forloop. It's a built-in keyword. Whenever you do this you're overriding functionality.
Don't use import *
With small scripts, it's not much of an issue, but as you start expanding your programs it becomes very easy to have clashing imports / unexpected behavior and in general it becomes a lot harder to keep track of things / debug.
e.g. - If we did import tkinter as some_name and we used some_name.* where * would be anything from tkinter you wanted to use such as tk.END as above, or even the widget classes it' a lot easier to keep track of. We know exactly where everything comes from.
Blocking Tk's main event loop
If you have a large directory then iterating like this will block Tk's main event loop. Consider using a separate thread instead.

Resources