Python tkinter Очистка текста метки - PullRequest
0 голосов
/ 21 февраля 2019

Я только начал использовать модуль Python tkinter для создания некоторых основных графических интерфейсов.В графическом интерфейсе, показанном ниже, пользователю предлагается выбрать индекс масла, и появится следующая информация о ценах (информация о ценах удалена).Однако я не нашел удобного способа очистки текста ценовой метки, когда пользователь выбирает другой индекс масла.У меня есть полный код ниже.Любые предложения будут ценны.Спасибо.

# 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**

Обновление: все еще небольшая проблема.
Сценарий: пользователь выбирает WTI Crude в качестве первого выбора, который показывает: «Последнее обновление: (задержка 11 минут)»

Затем пользователь выбираетМарс США, который должен показывать что-то вроде «Последнее обновление: (задержка 2 дня)»

Проблема: метки перекрывают друг друга, как показано на этом фото ПРИМЕР ФОТО Есть ли какое-либо решение для этого?

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Правильный способ - использовать StringVar для установки начального значения Label, тогда вам просто нужно вызвать .set() метод StringVar экземпляра, который вы хотите обновить.

Пример:

price_str = StringVar()
prica_label = Label(root, textvariable=price_str).pack()
price_str.set("new price")
0 голосов
/ 21 февраля 2019

Текст очистки метки:

, как сказал Джейсонхарпер.Используйте label.config (text = "кое-что")

Следующий скрипт показывает пример, где метка динамически увеличивается на 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()

ссылка: https://www.python -course.eu / tkinter_labels.php

ярлыки перекрываются:

вы не должны создавать ярлык снова и снова.

Кроме того, я думаю, что следующий пример будет лучше.

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


enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...