株価を追跡するアプリを作成しています。ユーザーには、エントリ ウィジェットと、ラベルとボタンで新しいフレームを作成するボタンを含むウィンドウが表示されます。ラベルは株価と銘柄、ボタンは削除ボタンで、クリックするとフレームが非表示になります。
私はこのプログラムを4回書き直しましたが、それは素晴らしい学習経験でしたが、私が学んだことは、メインのGUIクラスのメソッド部分から呼び出される「ミニフレーム」を持つことができないということです -これにより、削除ボタンが機能しなくなり、背後の値が更新されるframe.pack_forget()
ため、最後のアイテムのみが削除されます。
ミニフレーム ウィジェットを実際の株価のクラスに移動しました。私はそれらをパックしました(正しいと思います)が、表示されません。エラーも発生しないため、あまり役に立ちません。これが私のコードですが、フレームで何が起こっているかを示すために多くの機能部分を省略しています。に対するメソッドでupdater( 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()