Im in the middle of a small project, to create a tkinter gui that outputs the top ten posts from a user-defined subreddit from reddit.com using their api. Because I need to have the subreddit be the choice of the user, it needs to be inputted using a tkinter entry widget. However, the problem i'm having is that the widget does not refresh when the user puts in information, and instead it just outputs a bunch of numbers (".4302552760.4302552816.4367528344") right when the program launches. I can't seem to get this thing to just record what the user puts in as a string variable so I can run that through the next few classes and make the damn thing work. Ive hit a real roadblock here, and would really appreciate some help.
Ill give a few samples of the code, the whole thing, and then the specific problem areas:
The whole code is as follows:
import tkinter as tk
from functools import partial
from webbrowser import open
from datetime import date
import praw
'''Initialising the Applicaiton'''
class RedditScraper(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, redditReturn):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
'''The First Page the User will see'''
class StartPage(tk.Frame, object):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label1 = tk.Label(self, text="Start Page")
label1.pack(pady=10, padx=10)
'''label2 = tk.Label(self, text="Confirm This Subreddit", command= confirmSubreddit())
label2.pack(pady=10, padx=10)'''
button1 = tk.Button(self, text="Scrape This Subreddit", command=lambda: controller.show_frame(redditReturn))
button1.pack(pady=10, padx=10)
e1 = tk.Entry(self)
e1.pack(pady=10, padx=10)
StartPage.entry1 = e1
'''Adding brackets around the user's entry to the label to suffice the praw api'''
class bracketEntry(object):
def addBrackets(self):
user_entry_plus_brackets = '"' + str(StartPage.entry1) + '"'
print(user_entry_plus_brackets)
return user_entry_plus_brackets
'''Collecting data from reddit'''
class redditCollect(object):
def getSubreddit(self):
user_agent = "Simple Subreddit Scraper"
r = praw.Reddit(user_agent=user_agent)
'''remember to add the ability to get the user-defined subreddit information'''
user_entry = bracketEntry()
user_entry_variable = user_entry.addBrackets()
posts = r.get_subreddit("pics").get_hot(limit = 10)
return posts
'''The window containing the information from Reddit for the user'''
class redditReturn(tk.Frame, object):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
"""Creates all the buttons and frames for the GUI"""
get_user_entry = bracketEntry()
get_user_entry_string = get_user_entry.addBrackets()
intro = get_user_entry_string + " on Reddit: "
newFrame = tk.LabelFrame(self, text = intro)
newFrame.pack(fill="both", expand= True , anchor="nw")
row = 0
redditCollectGetter = redditCollect()
local_posts = redditCollectGetter.getSubreddit()
for p in local_posts:
gotoArticle = partial(open, p.url)
title = "(" + str(p.score) +") " + p.title
tk.Label(newFrame, text= title, pady= 10, wraplength= 700, justify= "left").grid(row= row, column= 0, sticky= "w")
tk.Button(newFrame, text= "Read more!", command= gotoArticle).grid(row= row+1, column= 0, sticky= "w")
tk.row = row + 2
app = RedditScraper()
app.mainloop()
Here is the class where I defined the entry widget (if this helps at all):
class StartPage(tk.Frame, object):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label1 = tk.Label(self, text="Start Page")
label1.pack(pady=10, padx=10)
'''label2 = tk.Label(self, text="Confirm This Subreddit", command= confirmSubreddit())
label2.pack(pady=10, padx=10)'''
button1 = tk.Button(self, text="Scrape This Subreddit", command=lambda: controller.show_frame(redditReturn))
button1.pack(pady=10, padx=10)
e1 = tk.Entry(self)
e1.pack(pady=10, padx=10)
StartPage.entry1 = e1
Here is where I am first trying to manipulate the entry to add parenthesis around it so it can work with the reddit api:
class bracketEntry(object):
def addBrackets(self):
user_entry_plus_brackets = '"' + str(StartPage.entry1) + '"'
print(user_entry_plus_brackets)
return user_entry_plus_brackets
I put print(user_entry_plus_brackets) here to show that it is outputting a bunch of numbers instead of the string that the user enters.
I am extremely new to python (and coding in general) and perhaps have gone over my head... Any help is really appreciated!
Thanks!
The thing about widgets is that when you coerce them to a string, they return their tkinter id. What you need to do is create a control variable (http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/control-variables.html) and associate it with your entry.
self.entry_var = tk.StringVar()
e1 = tk.Entry(self,textvariable=self.entry_var)
Instead of retrieving the value from the entry as you are doing:
str(StartPage.entry1)
you get the value of the control variable like this:
user_entry_plus_brackets = '"' + self.entry_var.get() + '"'
I'm not at home right now where I could test this out, but I believe that you should be able to get the value of the Entry using it's .get() method without needing to use a control variable:
user_entry_plus_brackets = '"' + self.entry1.get() + '"'