Reputation: 1814
I am creating an app to help me learn python. This app consists of a tkinter gui that displays news data that is scraped from multiple sites which are selected in the gui. The user can also enter date, two text fields, and two drop downs to be passed to the backed.
My problem is that the updated values entered into the gui, e.g. description text are not registering to the actual variables (variable.get()) i.e. the variables in the dictionary on the 4th last line are NULL.
If I hard code values in the dictionary, the dictionary passes without an issue.
I know my code is not the best but I am learning. Any help whatsoever is greatly appreciated because I have been stuck on this for a day and cannot find a solution anywhere online.
The issue is in the add button at the very bottom of my code.
from tkinter import *
from tkcalendar import *
import pandas as pd
from functools import partial
import datetime
from tkinter import ttk
class FrontEnd(object):
def __init__(self):
self.window = Tk()
self.window.geometry("1000x600")
self.enter_data()
self.buttons()
self.window.mainloop()
def enter_data(self):
"""Users will enter data here"""
#Category
self.cat_text = ttk.Label(self.window, width = 10, text = "Category")
self.cat_text.grid(row=5,column=0,rowspan=1,columnspan=1,sticky=W)
#list for category drop down
self.OptionList = [
"News"
, "Alert"
, "Recall"
, "Discussion"
]
self.variable = StringVar(self.window)
self.variable.set(self.OptionList[0]) # default value
self.w = ttk.OptionMenu(self.window, self.variable, *self.OptionList).grid(row=6,column=0,rowspan=1,sticky=W)
#Date
self.date_text = ttk.Label(self.window, width = 8, text = "Date")
self.date_text.grid(row=5,column=1,rowspan=1,columnspan=1,sticky=W)
#Enter date
self.date_picker = DateEntry(self.window)
self.date_picker.grid(row=6,column=1,rowspan=1,sticky=W)
#Sources
self.source_list = ["EC RASFF","IFSQN","FDA","FSAI","NZ FSA","UK FSA","USDA","USDA FSIS","IFS","FSSC","SF360","BRC","FSANZ","SQF","EFSA","UN FAO","CFIA","FDA FSMA","UN FAO","EC RAPID","WHO"]
self.source_text = ttk.Label(self.window, width = 8, text = "Source")
self.source_text.grid(row=5,column=2,rowspan=1,columnspan=1,sticky=W)
self.source_variable = StringVar(self.window)
self.source_variable.set(self.source_list[0]) # default value
#Description
self.desc_text = ttk.Label(self.window, width = 12, text = "Description:")
self.desc_text.grid(row=8,column=0,rowspan=1,columnspan=1,sticky=W)
self.desc_tb = Text(self.window,height = 1, width = 80)
self.desc_tb.grid(row=8,column=1,rowspan=1,columnspan=6,sticky=W)
#URL
self.url_text = ttk.Label(self.window, width = 12, text = "URL:")
self.url_text.grid(row=9,column=0,rowspan=1,columnspan=1,sticky=W)
self.url_tb = Text(self.window,height = 1, width = 80)
self.url_tb.grid(row=9,column=1,rowspan=1,columnspan=6,sticky=W)
self.s = ttk.OptionMenu(self.window, self.source_variable, *self.source_list).grid(row=6,column=2,rowspan=1,sticky=W)
self.outp = Listbox(self.window)
self.outp.grid(row=12,column=0,rowspan=1,columnspan=30,sticky=N+E+W+S)
def buttons(self):
#Send the entered data from enter_data to the backend
self.addtodf = ttk.Button(self.window, width = 12, text = "Add"
, command = partial(self.output_window,
({"category": self.variable.get(), "description": self.desc_tb.get('1.0', END), "link": self.desc_tb.get('1.0', END), "date" : self.date_picker.get_date(), "site_type": self.source_variable.get()})
)).grid(row=3,column=5,rowspan=1,columnspan=1,sticky=W)
def output_window(self,dict):
self.outp.insert(END, dict)
self.outp.insert(END, "\n")
if __name__ == "__main__":
app = FrontEnd()
Full project is here: https://github.com/seangibs/FoodNewsWebScraper
Upvotes: 0
Views: 692
Reputation: 12672
A careless problem.
In your __init__
function:
self.buttons()
When you create the app
instance,it will execute the function button
(the output_window
will be evaluate).At this time,All the variable are the values you run this code firstly.(The argument won't be change even if you select or type in other words.)
My suggestions:
button()
,just put it in the function enter_data()
.dict
is a struct python has defined.Use other variable name..get("0.0","end-1c")
could avoid \n
.Followed by your minimal example,all the code could be:
from tkinter import *
from tkcalendar import *
# import pandas as pd
from functools import partial
import datetime
from tkinter import ttk
class FrontEnd(object):
def __init__(self):
self.window = Tk()
self.window.geometry("1000x600")
self.enter_data()
self.window.mainloop()
def enter_data(self):
"""Users will enter data here"""
#Category
self.cat_text = ttk.Label(self.window, width = 10, text = "Category")
self.cat_text.grid(row=5,column=0,rowspan=1,columnspan=1,sticky=W)
#list for category drop down
self.OptionList = [
"News"
, "Alert"
, "Recall"
, "Discussion"
]
self.variable = StringVar(self.window)
self.variable.set(self.OptionList[0]) # default value
self.w = ttk.OptionMenu(self.window, self.variable, *self.OptionList).grid(row=6,column=0,rowspan=1,sticky=W)
#Date
self.date_text = ttk.Label(self.window, width = 8, text = "Date")
self.date_text.grid(row=5,column=1,rowspan=1,columnspan=1,sticky=W)
#Enter date
self.date_picker = DateEntry(self.window)
self.date_picker.grid(row=6,column=1,rowspan=1,sticky=W)
#Sources
self.source_list = ["EC RASFF","IFSQN","FDA","FSAI","NZ FSA","UK FSA","USDA","USDA FSIS","IFS","FSSC","SF360","BRC","FSANZ","SQF","EFSA","UN FAO","CFIA","FDA FSMA","UN FAO","EC RAPID","WHO"]
self.source_text = ttk.Label(self.window, width = 8, text = "Source")
self.source_text.grid(row=5,column=2,rowspan=1,columnspan=1,sticky=W)
self.source_variable = StringVar(self.window)
self.source_variable.set(self.source_list[0]) # default value
#Description
self.desc_text = ttk.Label(self.window, width = 12, text = "Description:")
self.desc_text.grid(row=8,column=0,rowspan=1,columnspan=1,sticky=W)
self.desc_tb = Text(self.window,height = 1, width = 80)
self.desc_tb.grid(row=8,column=1,rowspan=1,columnspan=6,sticky=W)
#URL
self.url_text = ttk.Label(self.window, width = 12, text = "URL:")
self.url_text.grid(row=9,column=0,rowspan=1,columnspan=1,sticky=W)
self.url_tb = Text(self.window,height = 1, width = 80)
self.url_tb.grid(row=9,column=1,rowspan=1,columnspan=6,sticky=W)
self.s = ttk.OptionMenu(self.window, self.source_variable, *self.source_list).grid(row=6,column=2,rowspan=1,sticky=W)
self.outp = Listbox(self.window)
self.outp.grid(row=12,column=0,rowspan=1,columnspan=30,sticky=N+E+W+S)
self.addtodf = ttk.Button(self.window, width=12, text="Add", command=self.output_window).grid(row=3, column=5, rowspan=1, columnspan=1, sticky=W)
def output_window(self):
self.outp.insert(END, {"category": self.variable.get(),
"description": self.desc_tb.get('0.0', "end-1c"),
"link": self.desc_tb.get('0.0', "end-1c"),
"date": self.date_picker.get_date(),
"site_type": self.source_variable.get()}) # don't get it by passing argument.Just get it in the function.
self.outp.insert(END, "\n")
if __name__ == "__main__":
app = FrontEnd()
Upvotes: 3
Reputation: 434
OK, so I see multiple problems there:
self.last_date
appears out of nowhere. What does this function do?self.buttons
gets called but not self.enter_data
so the OptionMenus and stuff does not exist so variables can't be changed. Furthermore don't even exist, which should lead to errors.self.source_variable
gets created but isn't assigned to any widget so can't by changed in the GUI itself.All in all I'm wondering how this code could even run. It's very confusing. I guess you either didn't gave us all the needed context (probably on the background of @jizhihaoSAMA telling you not to post the full code which is correct) or you messed up something there.
Please try to make an simple, cut down to the problem, program that reproduces your problem, so we can help you.
PS: Lines like self.s = ttk.OptionMenu(self.window, self.source_variable, *self.source_list).grid(row=6,column=2,rowspan=1,sticky=W)
aren't useful for you since grid
returns None
not the widget itself. You'd either need to create it and grid it in two steps like you did above or you can just get rid of the self.s =
-part since there is no use for that then.
Upvotes: 2