Python Tkinter Listbox file implementation - python

I am currently trying to insert data from an external file which I have defined with the function "browse" as shown below, and these data to implement inside the Listboxes which I have divided in 3 parts, the data in the external file is simply some dates and numbers which I will show below.
Could anyone help me figure out how do I implement data inside a Listbox as shown in the pictures below. P.S datesel() function is date selection to pick up dates manually after implementing the file inside of the listbox in which I am struggling to solve. Lastly Date Listboxes must be only integer as show in the picture 2.Data file link
Current results in 1st picture
Results that I need 2nd picture
Data file picture #3 that I implement through Button 1
from Tkinter import *
import tkFont , time
import ttk,csv,sys,os
import Tkinter,tkFileDialog
class Application(Frame):
def __init__(self,root):
Frame.__init__(self,root)
self.root=root
self.function1()
self.function2()
def function1(self): #tell the machine we are having new widget
self.frame1 = Frame(self.root)
self.frame3 = Frame(self.root, bg="lightblue", borderwidth=2, relief=GROOVE)
self.label1 = Label(self.frame1, text="Upload Acitivity File:")
self.first_button = Button(self.frame1, text="Button 1",command=self.browse)
#Start date selector
self.Sdate = Label(self.frame3, text="Start Date(dd/mm/yy): ")
self.Slb = Listbox(self.frame3, width = 6,height = 8,selectmode='multiple',exportselection=0)
self.Slb2 = Listbox(self.frame3, width=6, height=8,selectmode='multiple',exportselection=0)
self.Slb3 = Listbox(self.frame3, width=6, height=8,selectmode='multiple',exportselection=0)
def function2(self): # # tell the machine where our widget will be
self.frame1.pack()
self.frame3.pack()
self.label1.pack(padx=5, pady=10, side=LEFT)
self.first_button.pack(side=LEFT)
#start and end date
self.Sdate.grid(row =0,column=0)
self.Slb.grid(row =0,column=1)
self.Slb2.grid(row=0, column=2)
self.Slb3.grid(row=0, column=3)
def browse(self):
file = tkFileDialog.askopenfile(mode='rb', title='Choose a file')
self.data = csv.reader(file)
self.datalist = []
for row in self.data:
if len(row) != 0:
self.datalist = self.datalist + [row]
self.datalist.sort()
print self.datalist
def datesel(self):
# get selected line index
self.index = self.Slb.curselection()[0]
# get the line's text
self.seltext = self.Slb.get(self.index)
print self.seltext
self.index2 = self.Slb2.curselection()[0]
self.seltext2 = self.Slb2.get(self.index2)
print self.seltext2
self.index3 = self.Slb3.curselection()[0]
self.seltext3 = self.Slb3.get(self.index3)
print self.seltext3
self.Slist = [self.seltext,self.seltext2,self.seltext3]
self.Slist.sort(0,END)
print self.Slist
def main():
parent=Tk() # main frame
parent.geometry('600x600+300+30') #The height and width of the program
parent.title('Motion Tracker')#assign the title of the program
app = Application(parent)
parent.mainloop()#keeps the program running for infinite amount of time
main()

I don't understand why you want the day, month, and year in separate Listboxes, but anyway, here's some code that shows how to fill 3 Listboxes in the way your 2nd picture shows. I've reduced the code to the bare minimum, and I've hard-coded the filename into the class, but that's easy to fix.
import Tkinter as tk
class Application(tk.Frame):
def __init__(self, root):
tk.Frame.__init__(self, root)
self.pack()
self.root = root
self.do_listboxes()
def do_listboxes(self):
tk.Button(self, text="Get dates", command=self.fill_dates).pack()
self.Slb1 = tk.Listbox(self, width=6, height=8, selectmode='multiple', exportselection=0)
self.Slb2 = tk.Listbox(self, width=6, height=8, selectmode='multiple', exportselection=0)
self.Slb3 = tk.Listbox(self, width=6, height=8, selectmode='multiple', exportselection=0)
self.Slb1.pack(side=tk.LEFT)
self.Slb2.pack(side=tk.LEFT)
self.Slb3.pack(side=tk.LEFT)
def fill_dates(self):
fname = 'dkebz.txt'
# Use sets to get rid of duplicated days, months, and years
days, mons, yrs = set(), set(), set()
with open(fname, 'r') as f:
#Skip header
next(f)
for row in f:
# Extract the date from the row
date = row.split(',')[1]
# Extract the day, month, and year from the date
day, mon, yr = date.split('/')
days.add(day)
mons.add(mon)
yrs.add(yr)
# Populate the list boxes
for day in sorted(days):
self.Slb1.insert(tk.END, day)
for mon in sorted(mons):
self.Slb2.insert(tk.END, mon)
for yr in sorted(yrs):
self.Slb3.insert(tk.END, yr)
def main():
parent = tk.Tk()
parent.title('Motion Tracker')
app = Application(parent)
parent.mainloop()
main()
I've used import Tkinter as tk rather than from Tkinter import *. The "star" import dumps 175 Tkinter names into your namespace (in Python 3, 136 names), which is messy and can cause name collisions, especially if you do other "star" imports. Using import Tkinter as tk means that you have to prefix each Tkinter name with tk., so it involves a little more typing, but it makes the code easier to read because it's clear where each name comes from.

For that, you just need to modify the browse method. I have hard-coded the data to reflect what your file image showed. So if the data is exactly what you provided, this works. If it works for you, uncomment the 2 lines I commented, and delete the self.data list definition I wrote.
def browse(self):
file = tkFileDialog.askopenfile(title='Choose a file')
try:
with open(file, 'r') as reader:
self.data = list(reader)
except:
raise
self.datalist = []
for row in self.data:
if len(row) != 0 and not row.startswith('Activity'):
self.datalist = self.datalist + [row]
activity, date, steps = row.split(',')
month, day, year = date.split('/')
self.Slb.insert(END, month)
self.Slb2.insert(END, day)
self.Slb3.insert(END, year)

Related

I want to bind a function to a label in tkinter, been boggling me

I am still learning so bare with me
Basic explanation of the program:
Using Python3, and the tkinter module, I am making a little GUI just to learn the basics.
In the GUI there is a button, the idea is that when you click the button, a random verse of text (from a txt file) is displayed in another widget within the gui (a label in this case).
I can get the program to pull random verses from the text file, and print them in the shell, but not in the gui widget.
The code requires 2 files, the .py and the .txt
I uploaded them to a github repo so it may be easier to get an idea of the program there
Link to the project on github
However I will put the .py code here if it is more convenient that way but it won't run without the txt file.
import random
import tkinter as tk
from tkinter import *
class MainApplication(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
def random_line():
line_num = 0
selected_line = ''
with open('dhammapada.txt') as f:
while 1:
line = f.readline()
if not line: break
line_num += 1
if random.uniform(0, line_num) < 1:
selected_line = line
return(selected_line.strip())
def print_a_verse():
print('\n',random_line())
btn_result = Button(self, fg='Gold', text='New Verse', bg='Black', font='freesansbold, 16', command=print_a_verse) #textvariable=cvt_to, font='freesansbold, 16', fg='Blue')
btn_result.pack(fill=X,side=BOTTOM)#fill=BOTH, expand=1)
lbl_one = Label(self, bg='DarkGrey', fg='White', text='Dhammapada', font='freesansbold, 22')
lbl_one.pack(fill=BOTH, expand=1)
lbl_thr = Label(self, bg='DarkGrey', fg='White', text='The Dhammapada \nSiddartha Gautama - Buddha', font='freesansbold, 18')
lbl_thr.pack(fill=BOTH, expand=1)
lbl_two = Label(self, bg='DarkGrey', fg='Grey')
lbl_two.pack(fill=BOTH, expand=1)
if __name__ == "__main__":
root = tk.Tk()
root.minsize(400,400)
#root.configure(bg='Black')
root.title('Python - Dhammapada Verses')
MainApplication(root).pack(side="top", fill="both", expand=True)
root.mainloop()
I started that repo a few years back when I first got into coding, I was self-teaching online then because of pretty severe epilepsy I had to pretty much abandon sitting in front of a screen for hours so stopped it all. I think it was 2016. This is the first program I have looked at since, and the subject matter of the book has helped me a lot over the years.
I hope somebody can point me in the right direction. I may be making a mess of the whole thing already!
EDIT:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
Try this:
import tkinter as tk
from tkinter import *
class MainApplication(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
btn_result = Button(self, fg='Gold', text='New Verse', bg='Black', font='freesansbold, 16', command=self.print_a_verse) #textvariable=cvt_to, font='freesansbold, 16', fg='Blue')
btn_result.pack(fill=X,side=BOTTOM)#fill=BOTH, expand=1)
lbl_one = Label(self, bg='DarkGrey', fg='White', text='Dhammapada', font='freesansbold, 22')
lbl_one.pack(fill=BOTH, expand=1)
lbl_thr = Label(self, bg='DarkGrey', fg='White', text='The Dhammapada \nSiddartha Gautama - Buddha', font='freesansbold, 18')
lbl_thr.pack(fill=BOTH, expand=1)
lbl_two = Label(self, bg='DarkGrey', fg='Grey')
lbl_two.pack(fill=BOTH, expand=1)
def random_line(self):
return "testing text" # Just for testing
line_num = 0
selected_line = ''
with open('dhammapada.txt') as f:
while 1:
line = f.readline()
if not line: break
line_num += 1
if random.uniform(0, line_num) < 1:
selected_line = line
return(selected_line.strip())
def print_a_verse(self):
print(self.random_line())
if __name__ == "__main__":
root = tk.Tk()
root.minsize(400, 400)
#root.configure(bg='Black')
root.title('Python - Dhammapada Verses')
MainApplication(root).pack(side="top", fill="both", expand=True)
root.mainloop()
I moved all of the widget definitions inside your __init__ method and added self where appropriate to make sure it doesn't raise any errors. I would also suggest that you look at a quick object oriented programming tutorial.
I would start by only reading from the text file once, and storing all verses in a list. The way your code is written now, any time you call random_line, you're opening the file and closing it, which seems unnecessary.
Your method of selecting a random line isn't perfect, and could also be simplified - you read through the file, line by line, and occassionally decide to reassign selected_line depending on whether some random number is below an arbitrary threshold. There are several issues with this - there is no mechanism that prevents selected_line from being overwritten multiple times (which is unnecessary). There is also no guarantee that selected_line will ever be overwritten from its initial empty state. Additionally, the random number is generated via random.uniform(0, line_num) - since line_num increases with each iteration, the likelyhood that the random number will be below your threshold diminishes with each iteration. As a result, lines that are closer to the top of the file are more likely to be chosen.
The solution is to simply use random.choice to randomly select a verse from a list of all possible verses:
import tkinter as tk
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title("Random Verse")
self.geometry("256x256")
self.resizable(width=False, height=False)
self.button = tk.Button(self, text="Click", command=self.on_click)
self.button.pack()
self.label = tk.Label(self, text="", wraplength=200)
self.label.pack()
self.verses = self.get_verses("dhammapada.txt")
def get_verses(self, file_name):
with open(file_name, "r") as file:
verses = file.read().splitlines()
return verses
def on_click(self):
from random import choice
self.label["text"] = choice(self.verses)
def main():
Application().mainloop()
return 0
if __name__ == "__main__":
import sys
sys.exit(main())

How to deliver user input in Entry fields in tkinter to external classes/methods?

I am a novice Python programmer trying to write a compact GUI using Tkinter that will run a program that outputs a MS Excel file with a full loan amortization given the parameters entered in the GUI. My current issue is that every time I do enter input into the Entry fields and press the button that is supposed to create the file, it doesn't create a file with the title that I have entered, or any information thereafter. I can tell that whatever input is being put into the fields is not making it into the method that writes the .xlsx file.
I've tried rewriting the program several times, including working off of templates I found on the internet, and taking suggestions from older Stack Exchange forums. Important to note is that I have currently only implemented payments on a monthly basis into the code, so anytime the "Payments per year" input is filled out, it should be filled with 12.
Here is some of the relevant code.
import xlsxwriter
from tkinter import *
from tkinter import ttk
class Loan():
def __init__(self, payments_per_year):
self.payments_per_year = payments_per_year
class ExcelFile():
def __init__(self, file_name, loan):
self.file_name = file_name
self.loan = loan
def createFile(self):
workbook = xlsxwriter.Workbook(self.file_name + '.xlsx')
worksheet = workbook.add_worksheet(self.file_name)
worksheet.write('A1', 'Payments/year:')
worksheet.write('B1', self.loan.payments_per_year)
class Application(Frame):
def __init__(self, master=None):
self.master = master
Frame.__init__(self, master)
self.createWidgets()
def createWidgets(self):
mainframe = ttk.Frame(self.master)
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
ttk.Label(mainframe, text='Payments/yr: ').grid(column=2, row=6, sticky=E)
self.payments_per_year = IntVar()
payments_per_year_entry = ttk.Entry(mainframe, width=20, textvariable=self.payments_per_year)
payments_per_year_entry.grid(column=3, row=6, sticky=(W, E))
loan = Loan(self.payments_per_year)
excel_file = ExcelFile('Test name', loan)
create_xlsx_button = ttk.Button(mainframe, text="Create Excel File",
command=lambda: excel_file.createFile())
create_xlsx_button.grid(column=3, row=10, sticky=(W, E))
def run_program():
root = Tk()
app = Application(master=root)
app.mainloop()
if __name__ == '__main__':
run_program()
I expect to be able to input into the GUI and receive output in the form of an .xlsx file with the specified title and a payment-by-payment loan amortization. What I actually recieve is a .xlsx file titled '.xlsx' with no data.
GUI doesn't wait for user's data. And all in __init__ is executed at program's start so now you get values from entries at program's start when entries are empty.
You have to get values from entries in function which you run with Button
def __init__(...):
create_xlsx_button = ttk.Button(mainframe, text="Create Excel File", command=self.save_data)
def save_data(self):
self.initial_amount = self.initial_amount.get()
self.interest_rate = self.interest_rate.get() / 100.00
self.lifetime = self.lifetime.get()
# issue_datetime = datetime.datetime(issue_year.get(), issue_day.get(), issue_year.get())
self.issue_datetime = datetime.datetime(1900, 1, 1)
self.payments_per_year = self.payments_per_year.get()
self.file_name = self.file_name.get()
loan = Loan(self.initial_amount, self.interest_rate, self.lifetime, self.issue_datetime, self.payments_per_year)
excel_file = ExcelFile(self.file_name, loan)
excel_file.createFile()

add option to python tkinter optionmenu and execute a function when selected

Here is a much simplified version of what I was trying to do.
import Tkinter as tk
root = tk.Tk()
n = 1
def show1():
print var.get()
def add1():
global n
l = 'Option %d' % n
n += 1
op['menu'].add_command(label=l,command=tk._setit(var,l))
var.set(l)
print 'added %s' % l
var = tk.StringVar()
op = tk.OptionMenu(root,var,[], command=show1)
op.pack()
tk.Button(root,text='add 1', command=add1).pack()
tk.Button(root,text='show', command=show1).pack()
root.mainloop()
The 'add 1' button successfully adds options to the option menu.
Clicking on an option does not call the show1 routine, you have to click on the 'show' button.
-------Original Question-----
I'm trying to read in a number of selected files and save information about each of them.
As I read them in the file base name is stored in the option list. That seems to be working.
I would like to show the saved information when I click on a selection in the option menu. That is not working.
The code below is adding name to the option list, but you have to click the 'Get it' button to show the data.
#!/usr/bin/python2.7
import Tkinter as tk
import os,sys
import tkFileDialog as tkfd
class E(tk.Frame):
def __init__(self):
tk.Frame.__init__(self)
self.grid()
self.files = {}
self.statusMsg = tk.StringVar()
self.nLines = tk.StringVar()
self.maxLine = tk.StringVar()
self.fileName = tk.StringVar()
tk.Button(self,text='Get a file',command=self.openfile, bd=5).grid(row=1, column=0)
self.fileOption = tk.OptionMenu(self,self.fileName, [], command=self.getIt)
self.fileOption.configure(width=10, bd=5, relief='ridge')
self.fileOption.grid(row=2, column=0)
tk.Label(self,text='Line Count').grid(row=3, column=0)
tk.Label(self,textvariable=self.nLines).grid(row=3, column = 1)
tk.Label(self,text='Max Line').grid(row=4, column=0)
tk.Label(self,textvariable=self.maxLine).grid(row=4, column = 1)
tk.Button(self,text='show file',command=self.getIt, bd=5).grid(row=5)
tk.Label(self,text='Status').grid(row=6, column=0)
tk.Label(self,textvariable=self.statusMsg,width=20).grid(row=6, column = 1)
def openfile(self):
textFile = tkfd.askopenfile(mode='r', defaultextension='.txt',
filetypes=[("text","*.txt"),("All Files","*")],
initialdir='.')
(fileBaseName, fileExt) = os.path.splitext(os.path.basename(textFile.name))
maxLength = -1
lineCount = 0
for line in textFile:
lineCount += 1
maxLength = max(maxLength,len(line))
self.files[fileBaseName] = [maxLength,lineCount]
self.nLines.set(lineCount)
self.maxLine.set(maxLength)
self.statusMsg.set('Opened %s' % fileBaseName)
""" This works to add the file but the command is not
executed when selected in the optionmenu """
self.fileOption['menu'].add_command(label=fileBaseName, command=tk._setit(self.fileName,fileBaseName))
self.fileName.set(fileBaseName)
"""
fileList = sorted(self.files.keys())
for fname in fileList:
self.fileOption['menu'].add_command(label=fname, command=lambda v=fileList: self.getIt)
"""
"""
self.fileOption = tk.OptionMenu(self,self.fileName, fileList, command=self.getIt)
print fileList
"""
"""
self.fileOption['menu'].add_command(label=fileBaseName, command=tk._setit(self.fileName,fileBaseName))
self.fileOption.configure(command=self.getIt)
"""
"""
self.fileOption['menu'].add_command(label=fileBaseName, command=self.getIt)
"""
self.fileName.set(fileBaseName)
def getIt(self):
[maxLength,lineCount] = self.files[self.fileName.get()]
self.nLines.set(lineCount)
self.maxLine.set(maxLength)
self.statusMsg.set('got it')
if __name__ == "__main__":
app = E()
#app.title('Build Roof')
app.mainloop()
The comments show other things I've tried.
There are numerous examples of adding items to the option list and others that set the command, but none that do both.
P.S. I'd like to get rid of the pesky first blank entry in the option list
The solution turned out to be pretty simple. It works with a grid layout. Just leave an empty space where the OptionMenu needs to go and append new entries to a list. Then create a new OptionMenu as you add entries.
The OptionMenu doesn't even appear until you have at least one entry.
import Tkinter as tk
root = tk.Tk()
n = 1
vars=[]
def show1(*entry):
print var.get()
def add1():
global n
l = 'Option %d' % n
n += 1
vars.append(l)
op = tk.OptionMenu(root,var,*vars, command=show1).grid(row=0, column=1)
var.set(l)
print 'added %s' % l
var = tk.StringVar()
root.grid()
tk.Button(root,text='add 1', command=add1).grid(row=0, column=0)
tk.Label(root,text=' ', width=12).grid(row=0,column=1)
The Label in the last line doesn't need to be there if you have enough other things in the grid to keep the space open

Tkinter visual with Fill=X

the problem is realy simple, all funcions .packs(fill=X) for some reason don't work and in other hand if I use .pack(fill=X,pady=10) only pady works and fill=X is ignored. I hope that someone can explain to me why this is happing.
from tkinter import *
import json
import time
#opens file where pinger saves information about websites
def openfile():
d={}
with open('test.json', 'r') as f:
for line in f:
line_ = json.loads(line)
name = list(line_.keys())[0]
status = list(line_[name].keys())[0]
ip = line_[name][status]
d[name] = {'name':name, 'status':status, 'ip':ip}
f.close()
return d
#GUI main class
class GUI(Tk):
def __init__(self):
self.tk = Tk()
self.tk.configure(background='white')
self.tk.wm_state('zoomed')
self.label = {}
self.topFrame = Frame(self.tk, bg="white")
self.tk.after(5000, self.task)
self.title = Frame(self.tk, bg="white")
self.title.pack (side=TOP)
#self.topFrame.pack(side=TOP, expand=True)
self.topFrame.pack(side=TOP)
self.titlelbl= Label(self.title, text="Website Status: Green - Online, Red - Offline \n",bg="white", font=("Helvetica", 24))
self.titlelbl.pack(fill=X,pady=10)
#Funcion which creates and updates frame
def task(self):
i = 0
list={}
list = openfile()
if self.label != {}:#deleting previous information that we could refresh
for ele in self.label:
self.label[ele].destroy()
self.label= {}
for elem in list:#creating visual status if server is online text is in color green and opsite red
if list[elem]["status"]=="true":
lb = Label(self.topFrame, text=list[elem]["name"], fg="green",bg="white", font=("Helvetica", 24))
if list[elem]["status"]=="false":
lb = Label(self.topFrame, text=list[elem]["name"], fg="red",bg="yellow", font=("Helvetica", 24))
lb.pack(fill=X,pady=10)
self.label[elem] = lb
self.tk.after(5000, self.task)#Program refresh main window works every 5s
#forever loop
Gui= GUI()
Gui.mainloop()
You never expand / fill the frame widget, so the frame is only as large as necessary for it to hold all of it's children.
The padding options will increase the size (padding) of the children, and you'll be able to see the difference. Whereas with fill there's nothing for the child widget to fill it's already taking up as much space as it can in it's master (self.topFrame)

python tkinter append list

I am an amateur python programer with 2 months of experience. I am trying to write a GUI to-do list through tkinter. The actual placement of the buttons are not important. I can play around with those after. I need some help with displaying the appended item to the list. In the program, it updates well on the digit, but it won't print onto the list. I double checked it on the console and it says "tkinter.StringVar object at 0x102fa4048" but didn't update the actual list. What I need help is how can I update the list Main_Q on my the label column? Much appreciate some direction and coding help. Thanks.
Main_Q =["read","clean dishes", "wash car"]
from tkinter import*
root=Tk(className="total tasks in the Q")
#formula
def update():
global Main_Q
a=len(Main_Q)
num.set(a)
def add2list():
Main_Q.append(name)
a=len(Main_Q)
num.set(a)
print (Main_Q)
#output
num=StringVar()
y=Label(root, textvariable=num).grid(row=0, column=1)
#input
name=StringVar()
b=Entry(root, textvariable=name).grid(row=7,column=0)
#buttons
z=Button(root, text="update", command=update).grid(row=7, column=2)
add2list=Button(root,text="add", command=add2list).grid(row=7,
column=1)
r = 0
for c in Main_Q:
Label(text=c, relief=RIDGE,width=15).grid(row=r,column=0)
r = r + 1
root.mainloop()
Your problem is that your for loop which build up your labels doesnt get called after each time you have entered a new "task". To easily fix this you can move this loop into your update function.
If you want to prevent of looping through widget everytime you can create a new list with all widgets which already have been created:
createdWidgets = []
widgetsQueue = []
In your update function you than have to iterate through the widgetsQueue (widgetsQueue.pop() for instance), create the widgets and append the widget to the createdWidgetes list.
def update():
global Main_Q
r = 0
for c in Main_Q:
Label(text=c, relief=RIDGE,width=15).grid(row=r,column=0)
r += 1 # shorthand for r = r + 1
Some addition notes:
for the entry it is easier to seperate the definition and placement:
b = Entry(root)
b.grid(row=7,column=0)
because than Entry() returns its instance and you can use it to get the text:
b.get()
if you go shopping do you throw everything into one bag ?
from tkinter import *
does axactly that(in this case the globals() variable would be the bag).If you want to read more about that Importing Python Modules. To prevent that and shorten the amount of letters to type:
import tkinter as t # or tk
root = t.Tk()
*But for sure, if you just want a small program its okay.
Design:
To resolve your problem, you need to design this simple solution:
retrieve the text of the Tkinter.Entry widget using get() method.
add the text you got in 1 to Main_Q using append() method.
bind the button that updates on click both Main_Q and your GUI using command method.
create a new Tkinter.Label widget, set its text to the value you got in 1 and increment its corresponding row in the GUI.
I prefer to organize your code within a class that contains a constructor where Main_Q is initialized so that we call initialize_user_interface() to initialize the GUI with its three elements:
def __init__(self, parent):
Tkinter.Frame.__init__(self, parent)
self.parent = parent
self.Main_Q = ["read", "clean dishes", "wash car"]
self.r = 0 # position of the row of each label
self.initialize_user_interface()
The method initialize_user_interface() does what its name says. We mainly bind the function update_gui() that inserts a new label with the text set to what the user types in Tkinter.Entry widget using command = self.update_gui
ef initialize_user_interface(self):
self.parent.title("Update GUI")
self.parent.grid_rowconfigure(0, weight = 1)
self.parent.grid_columnconfigure(0, weight = 1)
for e in self.Main_Q:
Tkinter.Label(self.parent, anchor = Tkinter.W, text = e).grid(row = self.r, sticky = Tkinter.W)
self.r+=1
self.entry_text = Tkinter.Entry(self.parent)
self.entry_text.grid(row = 0, column = 1)
self.button_update = Tkinter.Button(self.parent, text = "Update", command = self.update_gui).grid(row = 1, column = 1, sticky = Tkinter.E)
Finally, nothing is simpler than update_gui() function:
def update_gui(self):
self.r+=1 # increment the row reserved to the new label
self.Main_Q.append(self.entry_text.get())
Tkinter.Label(self.parent, anchor = Tkinter.W, text = self.entry_text.get()).grid(row = self.r, sticky = Tkinter.W)
Programming the application:
Here is the full program:
'''
Created on Mar 11, 2016
#author: Bill BEGUERADJ
'''
import Tkinter
class Begueradj(Tkinter.Frame):
def __init__(self, parent):
Tkinter.Frame.__init__(self, parent)
self.parent = parent
self.main_queue = ["read", "clean dishes", "wash car"]
self.r = 0
self.initialize_user_interface()
def initialize_user_interface(self):
self.parent.title("Update GUI")
self.parent.grid_rowconfigure(0, weight = 1)
self.parent.grid_columnconfigure(0, weight = 1)
for e in self.main_queue:
Tkinter.Label(self.parent, anchor = Tkinter.W, text = e).grid(row = self.r, sticky = Tkinter.W)
self.r+=1
self.entry_text = Tkinter.Entry(self.parent)
self.entry_text.grid(row = 0, column = 1)
self.button_update = Tkinter.Button(self.parent, text = "Update", command = self.update_gui).grid(row = 1, column = 1, sticky = Tkinter.E)
def update_gui(self):
self.r+=1
self.main_queue.append(self.entry_text.get())
Tkinter.Label(self.parent, anchor = Tkinter.W, text = self.entry_text.get()).grid(row = self.r, sticky = Tkinter.W)
def main():
root = Tkinter.Tk()
b = Begueradj(root)
root.mainloop()
if __name__ == "__main__":
main()
Demo:
Here is a screenshot of the running program:
Note:
I coded the previous program using Python 2.7, so if you want to test it, please change Tkinter to tkinter. Everything else remains the same.

Categories