【问题标题】:Python Tkinter frame inside frame limitation or user error?Python Tkinter 框架内的框架限制或用户错误?
【发布时间】:2013-09-19 15:55:37
【问题描述】:

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

我已经重写了这个程序 4 次,这是一次很棒的学习经历,但我学到的是我不能从 main 的方法部分调用“迷你框架” GUI 类 - 这对删除按钮进行了修改,并更新了 frame.pack_forget() 后面的值,因此它只删除了最后一个项目。

我已将我的迷你框架小部件移至实际库存值的类中。我已经打包好它们(我认为是正确的),但它们没有出现。他们也不会出错,这不是很有帮助。这是我的代码,虽然我省略了很多功能部分来显示我的框架发生了什么。请记住,我需要保留它,以便我可以使用 .after 方法针对 myapp.myContainer 调用我的更新程序 (self.update_stock_value)。

有没有更好的方法来做到这一点?先谢谢了,我头疼。

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

【问题讨论】:

  • 这段代码不完整——没有调用 mainloop 并且你永远不会创建 MyApp 的实例。当我修复它时,我会遇到更多错误。当我修复这些时,我会得到更多。你能给我们一个完整的、有效的程序吗?
  • 我已经用我现在正在使用的完整代码进行了编辑。请记住,我报废了我的工作应用程序并重新构建它,我遇到了这个问题,所以功能可能不存在。

标签: python class user-interface tkinter frames


【解决方案1】:

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

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

【讨论】:

  • 呃,谢谢。你摇滚。我真的很喜欢你在这里设计的布局。感谢您不断回答这些问题!
猜你喜欢
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 2020-07-02
  • 1970-01-01
  • 2021-08-29
  • 1970-01-01
  • 2020-07-10
相关资源
最近更新 更多