Tobias Funke
Tobias Funke

Reputation: 1814

Tkinter entered values not updating

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

Answers (2)

jizhihaoSAMA
jizhihaoSAMA

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:

  1. Don't use function button(),just put it in the function enter_data().
  2. dict is a struct python has defined.Use other variable name.
  3. Use .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

Nummer_42O
Nummer_42O

Reputation: 434

OK, so I see multiple problems there:

  • The function 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

Related Questions