Entry Widget сводит меня с ума !: Tkinter Reddit Scraper думает, что строковая запись - это числа?

Я нахожусь в середине небольшого проекта, чтобы создать tkinter gui, который выводит десять лучших сообщений из определяемого пользователем субреддита с reddit.com, используя их api. Поскольку мне нужно, чтобы сабреддит был выбран пользователем, его нужно вводить с помощью виджета входа tkinter. Однако проблема, с которой я столкнулся, заключается в том, что виджет не обновляется, когда пользователь вводит информацию, а вместо этого просто выводит кучу чисел («.4302552760.4302552816.4367528344») прямо при запуске программы. Кажется, я не могу заставить эту штуку просто записывать то, что пользователь вводит в виде строковой переменной, чтобы я мог пропустить это через следующие несколько классов и заставить эту чертову штуку работать. Я оказался здесь настоящим препятствием и был бы очень признателен за помощь.

Я приведу несколько примеров кода, целиком, а затем конкретные проблемные области:

Весь код выглядит следующим образом:

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()

Вот класс, в котором я определил виджет входа (если это вообще помогает):

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

Вот где я сначала пытаюсь манипулировать записью, чтобы добавить вокруг нее круглые скобки, чтобы она могла работать с api reddit:

class bracketEntry(object):
    def addBrackets(self):
        user_entry_plus_brackets = '"' + str(StartPage.entry1) + '"'
        print(user_entry_plus_brackets)
        return user_entry_plus_brackets

Я помещаю здесь print (user_entry_plus_brackets), чтобы показать, что он выводит набор чисел вместо строки, которую вводит пользователь.

Я очень новичок в python (и кодировании в целом) и, возможно, перебил себе голову ... Любая помощь действительно приветствуется!

Спасибо!


person JeffD    schedule 02.06.2015    source источник


Ответы (1)


Особенность виджетов в том, что когда вы приводите их к строке, они возвращают свой идентификатор tkinter. Вам нужно создать управляющую переменную (http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/control-variables.html) и свяжите его со своей записью.

self.entry_var = tk.StringVar()
e1 = tk.Entry(self,textvariable=self.entry_var)

Вместо того, чтобы извлекать значение из записи, как вы это делаете:

str(StartPage.entry1)

вы получите значение управляющей переменной следующим образом:

user_entry_plus_brackets = '"' + self.entry_var.get() + '"'

Я сейчас не дома, где я мог бы это проверить, но я считаю, что вы сможете получить значение Entry, используя его метод .get (), без необходимости использовать контрольную переменную:

user_entry_plus_brackets = '"' + self.entry1.get() + '"'
person dusty    schedule 02.06.2015
comment
Строго говоря, вам не нужна управляющая переменная для этого. Это одно решение, но не единственное. Ваш последний абзац правильный, вы можете использовать метод get() без добавления дополнительной управляющей переменной. - person Bryan Oakley; 03.06.2015
comment
Привет, Брайан, мой код теперь выдает ошибку: TypeError: __init __ () отсутствует 2 обязательных позиционных аргумента: 'parent' и 'controller'. Я понятия не имею, как это исправить, и он никогда не появлялся раньше, у вас есть отвечать? Спасибо! - person JeffD; 03.06.2015