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

时间:2013-09-19 15:55:37

标签: python class user-interface tkinter frames

我一直在构建一个应用程序来跟踪股票价格。用户应该看到一个带有条目小部件的窗口和一个创建带有标签和按钮的新框架的按钮。标签是股票价格和符号,按钮是删除按钮,如果点击则应隐藏该框架。

我现在已经重写了这个程序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 个答案:

答案 0 :(得分:1)

由于存在大量错误,您的代码将无法运行,但这一行肯定没有按照您的想法执行:

self.frame.pack

要调用包功能,您必须包含(),例如:

self.frame.pack()

您询问您的代码是否是执行此操作的最佳方式。我认为你走在正确的轨道上,但我会改变一些事情。这是我如何构建代码。这只是创建了“miniframes”,它没有做任何其他事情:

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