简体   繁体   English

Python tkinter 清除标签文本

[英]Python tkinter Clearing Label Text

I have just started utilizing Python's tkinter module to create some basic GUIs.我刚刚开始使用 Python 的 tkinter 模块来创建一些基本的 GUI。 In the GUI shown below, the user is prompted to select an oil index and subsequent pricing information will appear (the price information is web scraped).在如下所示的 GUI 中,会提示用户选择一个石油指数,随后会出现价格信息(价格信息是网络抓取的)。 However, I have not found a convenient way to clear the pricing label text for when the user selects another oil index.但是,我还没有找到一种方便的方法来清除用户选择另一个石油指数时的定价标签文本。 I have the full code attached below.我在下面附上了完整的代码。 Any suggestions would be greatly appreciated.任何建议将不胜感激。 Thank you.谢谢你。

# Import Python Modules
from tkinter import *
from ttk import *
import urllib2
from bs4 import BeautifulSoup
import re

# Generate Basic Window
root = Tk()
root.geometry("225x125")
root.resizable(0,0)
root.title("Global Oil Price GUI")

# Functions
def fetchdata(event):

    index = combo.current() # Get index of combobox selection
    # Obtain HTML
    url = 'http://oilprice.com/oil-price-charts/45' # URL to be scraped
    content = urllib2.urlopen(url)
    parsed = BeautifulSoup(content,'html.parser')

    # Parse HTML
    oilprice = parsed.findAll('td',attrs = {'class': 'last_price'})
    change = parsed.findAll('td',{'class':['change_up flat_change_cell','change_down flat_change_cell','change_up','change_down']})
    change_percent = parsed.findAll('td',{'class':['change_up_percent percent_change_cell','change_down_percent percent_change_cell','change_up_percent','change_down_percent']})

    # Pre-Initialize Arrays
    oilprice_extract = []
    change_extract = []
    change_percent_extract = []
    time_extract = []

    # Loop and Extract Text
    for ele_price, ele_change, ele_change_percent in zip(oilprice,change,change_percent):
        oilprice_extract.append(float(ele_price.text))
        change_extract.append(ele_change.text)
        change_percent_extract.append(ele_change_percent.text.split('%')[0] + '%')
        time_extract.append(re.sub('\n\t',' ',ele_change_percent.text.split('%')[1]))

    # Fill Field Based Upon Selection
    price_label = Label(root,text = oilprice_extract[index]).grid(row = 2,column = 2)
    change_label = Label(root,text = change_extract[index]).grid(row = 3,column = 2)
    change_percent_label = Label(root,text = change_percent_extract[index]).grid(row = 4,column = 2)
    update_label = Label(root,text = time_extract[index]).grid(row = 5,column = 2)

# Driver Code
combo_label = Label(root,text = "Futures & Indexes",justify = LEFT).grid(row = 0, column = 0)
combo = Combobox(root,values = ["WTI Crude","Brent Crude","Mars US","OPEC Basket","Canadian Crude Index"],width = 17)
combo.grid(row = 1, column = 0)
combo.bind("<<ComboboxSelected>>",fetchdata)

price_display = Label(root,text = " Price (USD):").grid(row = 2,column = 0)
change_display = Label(root,text = "Change:").grid(row = 3,column = 0)
change_percent_display = Label(root,text = "Change Percent:").grid(row = 4,column = 0)
update_display = Label(root,text = "Last Updated:").grid(row = 5,column = 0)

root.mainloop() # Run window continuously**

Update: Still a slight problem.更新:仍然是一个小问题。
Scenario: User selects WTI Crude as first choice which shows: 'Last Update: (11 Minutes Delay)'场景:用户选择 WTI 原油作为第一选择,显示:“上次更新:(11 分钟延迟)”

User then selects Mars US which should show something like 'Last Update: (2 Days Delay)'用户然后选择火星美国,它应该显示类似“上次更新:(2天延迟)”的内容

Problem: The labels overlap each other as shown in this photo EXAMPLE PHOTO Any solution to this?问题:标签彼此重叠,如这张照片示例照片 有解决方案吗?

Clearing Label Text:清除标签文本:

as jasonharper said.正如杰森哈珀所说。 Use label.config(text="something")使用label.config(text="something")

The following script shows an example, where a label is dynamically incremented by 1 until the stop button is pressed:以下脚本显示了一个示例,其中标签动态递增 1,直到按下停止按钮:

import tkinter as tk

counter = 0 
def counter_label(label):
  def count():
    global counter
    counter += 1
    label.config(text=str(counter))
    label.after(1000, count)
  count()


root = tk.Tk()
root.title("Counting Seconds")
label = tk.Label(root, fg="green")
label.pack()
counter_label(label)
button = tk.Button(root, text='Stop', width=25, command=root.destroy)
button.pack()
root.mainloop()

reference: https://www.python-course.eu/tkinter_labels.php参考: https : //www.python-course.eu/tkinter_labels.php

labels overlap:标签重叠:

you shouldn't recreate label over and over again.你不应该一遍又一遍地重新创建标签。

Besides, I think the following example will be better.此外,我认为下面的例子会更好。

from tkinter import *
from tkinter.ttk import *
import requests
from tkinter.ttk import Combobox
from bs4 import BeautifulSoup, SoupStrainer
# import re  # As long as you can make do with str.replace(), you should use it instead of re.sub.


class CQueryOil(Tk):

    def __init__(self, query_country: list):
        super().__init__()  # init Tk
        self.__url = 'http://oilprice.com/oil-price-charts/45'
        self._query_country = query_country
        self._intvar_price = IntVar()
        self._strvar_change = StringVar(value='')
        self._strvar_change_percent = StringVar(value='')
        self._strvar_update_time = StringVar(value='')
        self.init_ui()

    @property
    def url(self):
        return self.__url

    @property
    def query_list(self):
        return self._query_country

    def run(self):
        self.mainloop()

    def init_ui(self) -> None:
        self.geometry("225x125")
        self.resizable(0, 0)
        self.title("Global Oil Price GUI")
        [self.grid_columnconfigure(col, weight=1) for col in (1, 2)]

        n_padx = 5
        Label(self, text="Futures & Indexes", justify=LEFT).grid(row=0, column=0, padx=n_padx, sticky='w')
        combo = Combobox(self, values=self.query_list, width=17)
        combo.grid(row=1, column=0, padx=n_padx, columnspan=2, sticky='w')
        combo.bind("<<ComboboxSelected>>", lambda event: self.update(event, combo=combo))

        for cur_row, label_name in enumerate(['Price (USD):', 'Change:', 'Change Percent:', 'Last Updated:']):
            Label(self, text=label_name, width=14).grid(row=2 + cur_row, column=0, padx=n_padx, sticky='e')

        Label(self, textvariable=self._intvar_price).grid(row=2, column=1, sticky='w')
        Label(self, textvariable=self._strvar_change).grid(row=3, column=1, sticky='w')
        Label(self, textvariable=self._strvar_change_percent).grid(row=4, column=1, sticky='w')
        Label(self, textvariable=self._strvar_update_time).grid(row=5, column=1, sticky='w')

    def update(self, event, combo) -> None:
        resp = requests.get(self.url)
        if resp.status_code != 200:
            return

        filter_data = SoupStrainer('tr', attrs={'class': ['stripe show_graph', 'stripe show_graph update_on_load']
                                                # 'data-id': ['45', '46', '50', '29', '68']
                                                })
        parsed = BeautifulSoup(resp.text, 'lxml', parse_only=filter_data)

        idx = combo.current()  # Get index of combobox selection
        try:
            dst_td_tags = parsed.find('td', string=self.query_list[idx]).find_next_siblings()
        except:
            import traceback
            print(traceback.format_exc())
            raise NameError(f'====Must match the data on the web page. Name:{self.query_list[idx]}=====')  # literal format Py3.6↑
        dst_list = [td.text for td in dst_td_tags]

        price, change, change_percent, update_time = dst_list
        change_percent = change_percent.split('%')[0]  # As long as you can make do with str.replace(), you should use it instead of re.sub.
        update_time = update_time.replace('\n\t', ' ')
        change_percent = change_percent
        update_time = update_time

        self._intvar_price.set(price)
        self._strvar_change.set(change)
        self._strvar_change_percent.set(change_percent)
        self._strvar_update_time.set(update_time)


if __name__ == '__main__':
    obj = CQueryOil(["WTI Crude", "Brent Crude", "Mars US", "Opec Basket", "Canadian Crude Index"])  # Must match the data on the web page
    obj.run()


在此处输入图片说明

The correct way is to use a StringVar to set the initial value of the Label , then you just need to call the .set() method of the StringVar instance you want to update.正确的做法是使用StringVar来设置Label的初始值,然后只需要调用要更新的StringVar实例的.set()方法即可。

Example:例子:

price_str = StringVar()
prica_label = Label(root, textvariable=price_str).pack()
price_str.set("new price")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM