代码之家  ›  专栏  ›  技术社区  ›  ford

Python Tkinter框架内部框架限制或用户错误?

  •  0
  • ford  · 技术社区  · 11 年前

    我一直在开发一个追踪股价的应用程序。用户应该看到一个带有入口小部件和按钮的窗口,该窗口创建了一个带有标签和按钮的新框架。标签是股票价格和符号,按钮是一个删除按钮,如果单击,应该会隐藏该框。

    我已经重写了4次这个程序,这是一次很棒的学习经历,但我学到的是,我不能让“迷你框架”从主GUI类的方法部分调用——这会使删除按钮变乱,并更新后面的值 frame.pack_forget() 所以它只删除最后一个项目。

    我已经将我的迷你框架小部件向下移动到类中,以获得实际的股票价值。我已经把它们打包了(我认为是正确的),但它们没有出现。它们也不会出错,这并没有多大帮助。这是我的代码,尽管我省略了很多功能部分来显示我的框架发生了什么。请记住,我需要保留它,这样我才能调用更新程序( self.update_stock_value )带有 .after 反对的方法 myapp.myContainer .

    有更好的方法吗??提前谢谢,我的头很疼。

    import re
    import time
    import urllib
    from Tkinter import *
    import threading
    from thread import *
    
    runningThreads = 0
    
    # each object will be added to the gui parent frame
    class MyApp(object):
        def __init__(self, parent):
            self.myParent = parent
            self.myContainer = Canvas(parent)
            self.myContainer.pack()
            self.create_widgets()
    
        # METHOD initiates basic GUI widgets
        def create_widgets(self):
            root.title("Stocker")
            self.widgetFrame = Frame(self.myContainer)
            self.widgetFrame.pack()
    
            self.input = Entry(self.widgetFrame)
            self.input.focus_set()
            self.input.pack()
    
            self.submitButton = Button(self.widgetFrame, command = self.onButtonClick)
            self.submitButton.configure(text = "Add new stock")
            self.submitButton.pack(fill = "x")
    
        # METHOD called by each stock object
        # returns the "symbol" in the entry widget
        # clears the entry widget
        def get_input_value(self):
            var = self.input.get()
            self.input.delete(0, END)
            return var
    
        # METHOD called when button is clicked
        # starts new thread with instance of "Stock" class
        def onButtonClick(self):
            global runningThreads # shhhhhh im sorry just let it happen
            runningThreads += 1 # count the threads open
            threading.Thread(target = self.init_stock,).start() # force a tuple
            if runningThreads == 1:
                print runningThreads, "thread alive"
            else:
                print runningThreads, "threads alive"
    
        def init_stock(self):
            new = Stock()
    
    class Stock(object):
        def __init__(self):
            # variable for the stock symbol
            symb = self.stock_symbol()
            # lets make a GUI
            self.frame = Frame(myapp.myContainer)
            self.frame.pack
            # give the frame a label to update
            self.testLabel = Label(self.frame)
            self.testLabel.configure(text = self.update_stock_label(symb))
            self.testLabel.pack(side = LEFT)
            # create delete button to kill entire thread
            self.killButton = Button(self.frame, command = self.kill_thread)
            self.killButton.configure(text = "Delete")
            self.killButton.pack(side = RIGHT)
            # create stock label
            # call updater
    
        def kill_thread(self):
            global runningThreads
            runningThreads -= 1
            self.stockFrame.pack_forget() # hide the frame
            self.thread.exit()  # kill the thread
    
        def update_stock_label(self, symb):
            self.testLabel.configure(text = str(symb) + str(get_quote(symb)))
            myapp.myContainer.after(10000, self.update_stock_label(symb))
    
        def stock_symbol(self):
            symb = myapp.get_input_value()
            print symb
    
    
    
    
    # The most important part!
    def get_quote(symbol):
        try:
            # go to google
            base_url = "http://finance.google.com/finance?q="
            # read the source code
            content = urllib.urlopen(base_url + str(symbol)).read()
            # set regex target
            target = re.search('id="ref_\d*_l".*?>(.*?)<', content)
            # if found, return.
            if target:
                print "found target"
                quote = target.group(1)
                print quote
            else:
                quote = "Not Found: "
            return quote
         # handling if no network connection
         except IOError:
             print "no network detected"
    
    
    root = Tk()
    root.geometry("280x200")
    myapp = MyApp(root)
    root.mainloop()
    
    1 回复  |  直到 11 年前
        1
  •  1
  •   Bryan Oakley    11 年前

    由于大量错误,您的代码不会运行,但这一行肯定没有做您认为它正在做的事情:

    self.frame.pack
    

    要调用pack函数,必须包含 () ,例如:

    self.frame.pack()
    

    您会问您的代码是否是实现这一点的最佳方法。我认为你走在了正确的道路上,但我会改变一些事情。以下是我将如何构建代码。这只是创建“迷你框架”,它不做任何其他事情:

    import Tkinter as tk
    
    class Example(tk.Frame):
        def __init__(self, parent):
            tk.Frame.__init__(self, parent)
    
            self.entry = tk.Entry(self)
            self.submit = tk.Button(self, text="Submit", command=self.on_submit)
            self.entry.pack(side="top", fill="x")
            self.submit.pack(side="top")
    
        def on_submit(self):
            symbol = self.entry.get()
            stock = Stock(self, symbol)
            stock.pack(side="top", fill="x")
    
    
    class Stock(tk.Frame):
        def __init__(self, parent, symbol):
            tk.Frame.__init__(self, parent)
            self.symbol = tk.Label(self, text=symbol + ":")
            self.value = tk.Label(self, text="123.45")
            self.symbol.pack(side="left", fill="both")
            self.value.pack(side="left", fill="both")
    
    root = tk.Tk()
    Example(root).pack(side="top", fill="both", expand=True)
    root.mainloop()