Кнопка Tkinter для обновления данных с помощью вызова API

#python #tkinter

#python #tkinter

Вопрос:

Я полный новичок в библиотеке Tkinter и вызове функций, поэтому я обращаюсь к вам за помощью:

Я пытаюсь создать виджет для проверки цен на криптовалюту и PNL.

До сих пор я создавал вызов API CoinGecko внутри функции, чтобы вернуть мне фрейм данных и результат PNL. Я также создал графический интерфейс с помощью Tkinter.

Мой текущий скрипт выглядит так:

 from pycoingecko import CoinGeckoAPI
import pandas as pd
import datetime
from tkinter import *
import time

def get_crypto_data():
    data = []
    cg = CoinGeckoAPI()
    coins = cg.get_price(ids='bitcoin,ethereum,,neo,ripple', vs_currencies='usd', include_24hr_change='true')
    df = pd.DataFrame.from_dict(coins, orient='index')

    PNL = "something"
    data.append(df)
    data.append(PNL)

    return data

def Click():
    get_crypto_data()

def setup_GUI(mask,crypto_data, click):

    mask.wm_title("Live Portfolio Data")

    date_time = datetime.datetime.now().strftime("%A %d.%m.%Y %H:%M:%S")

    l1 = Label(mask,bg='blue', text= "Live Crypto portfolio Data")
    l1.grid(row=0, column=0)
    l2 = Label(mask,bg='yellow', text= date_time)
    l2.grid(row=1, column=0)
    l3 = Label(mask,bg='yellow', text=crypto_data[0])
    l3.grid(row=2, column=0)
    l4 = Label(mask, bg='yellow', text=crypto_data[1])
    l4.grid(row=3, column=0)
    butt = Button(mask, padx=2, bd=2, fg="black", font=('arial', 20, 'bold'),
                   text="Button", bg="yellow", command=lambda: Click())
    butt.grid(row=5, column=0)
    mask.geometry("500x500")
    mask.configure(bg='yellow')
    return mask

def main():

    while True:

        mask = Tk()
        crypto_data = get_crypto_data()
        click = Click()
        mask = setup_GUI(mask,crypto_data,click)
        mask.update()
        mask.mainloop()

if __name__ == '__main__':
    main()
 

То, что я пытаюсь сделать, это вызвать Button API и обновить dataframe и PNL и показать это на моей маске.

Есть ли у вас какие-либо идеи, как это сделать? Я думаю, это не так сложно, но я не знаю, где искать 🙂

Спасибо!

Ответ №1:

Вы должны создать подкласс tkinter.Tk . Я соответствующим образом отредактировал ваш код:

 from pycoingecko import CoinGeckoAPI
import pandas as pd
import datetime
from tkinter import *
import time

class Window(Tk):
    def __init__(self):
        Tk.__init__(self) # initiate the window
    
    def setup_ui(self):
        self.wm_title("Live Portfolio Data")

        date_time = datetime.datetime.now().strftime("%A %d.%m.%Y %H:%M:%S")

        self.l1 = Label(self, bg="blue", text="Live Crypto portfolio Data")
        self.l1.grid(row=0, column=0)
        self.l2 = Label(self, bg="yellow", text=date_time)
        self.l2.grid(row=1, column=0)
        self.l3 = Label(self, bg="yellow", text="placeholder") # placeholder will be replaced with correct values
        self.l3.grid(row=2, column=0)
        self.l4 = Label(self, bg="yellow", text="placeholder")
        self.l4.grid(row=3, column=0)
        butt = Button(self, padx=2, bd=2, fg="black", font=("arial", 20, "bold"),
                   text="Button", bg="yellow", command=self.update_data) # when the user clicks the button, fetch the data again and update the labels
        butt.grid(row=5, column=0)
        self.geometry("500x500")
        self.configure(bg="yellow")
        self.update_data() # call update_data once to display correct values on the labels

    def update_data(self, *args): # *args makes accept this function any number of arguments, args will be a list with all arguments
        self.data = [] # make data a member of this class
        cg = CoinGeckoAPI()
        coins = cg.get_price(ids="bitcoin,ethereum,neo,ripple", vs_currencies="usd", include_24hr_change="true")
        df = pd.DataFrame.from_dict(coins, orient="index")

        PNL = "something"
        self.data.append(df)
        self.data.append(PNL)
        
        date_time = datetime.datetime.now().strftime("%A %d.%m.%Y %H:%M:%S") # if you do not want
        self.l2.config(text=date_time) # the time to be updated, remove these two lines
        
        # update labels with values got above
        self.l3.config(text=self.data[0])
        self.l4.config(text=self.data[1])

def main():
    mask = Window() # create window
    mask.setup_ui() # create labels, buttons, etc.
    mask.update() # make sure everything shows up correctly
    mask.mainloop() # now show the window

if __name__ == "__main__":
    main()
 

Пожалуйста, используйте одинарные кавычки ( ' ) ИЛИ двойные кавычки ( " ) везде в вашем коде. Для python не проблема использовать оба смешанных, но это делает код более читаемым, чтобы НЕ смешивать их.

Комментарии:

1. Спасибо за оперативную помощь, но, честно говоря, я не совсем понимаю, как это работает. Даже если я запускаю ваш скрипт, он показывает ошибку: у объекта ‘_tkinter.tkapp’ нет атрибута ‘l3’, не могли бы вы немного расширить?

2. @MachuPichu92 да, позже этим вечером!

3. @MachuPichu92 я отредактировал свой ответ, теперь он работает без ошибок, и я добавил комментарии, объясняющие, что делает код

4. @MachuPichu92 я должен признать, что я не тестировал свой первый код;) извините за это

5. фредерик: Большое спасибо за дополнительные объяснения и ваше время!