Once again I am here asking for guidance with my crypto trading bot. This time, I am trying to update variables using Tkinter Entries. The default value for the Entry that I am trying to update is Crypto Symbol. I am trying to get a variable sym from this to use with the Binance API. I need to do sym = crypto.get()+'USDT' to get the variable that I need to plug into the command for the Trade button. For testing purposes, I set the command to print(sym) because I am trying to get it to update and that makes it easy to see what is going on. When I press the button, no matter what I have entered in the Entry, it always spits out Crypto SymboUSDT because Crypto Symbol is the original value, showing that what I am entering doesn't change anything. I will attach my code below, if you have a potential fix, please let me know :)
import pandas as pd
from pandas.core import frame, indexing
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import tkinter as tk
from tkinter import *
from tkinter.ttk import *
from tkinter import Entry, Tk, filedialog, Text
root = tk.Tk()
root.geometry('500x250')
root.title('Binance Bot')
# API Key Information
api_key = 'Censored'
api__secret = 'Censored'
# Entries
#Crypto Symbol
crypto = Entry(root, width=20, borderwidth=2, fg='gray')
crypto.insert(0, "Crypto Symbol")
def cryptoFocusIn(event):
crypto.config(foreground='black')
if crypto.get() == 'Crypto Symbol':
crypto.config(foreground='black')
crypto.delete(0, END)
def cryptoFocusOut(event):
if crypto.get() == '':
crypto.delete(0, END)
crypto.config(foreground='gray')
crypto.insert(0, 'Crypto Symbol')
crypto.bind('<FocusIn>', cryptoFocusIn)
crypto.bind('<FocusOut>', cryptoFocusOut)
crypto.pack()
sym = crypto.get()+'USDT'
# Order amount
OrderAmt = Entry(root, width=20, borderwidth=2, fg='gray')
OrderAmt.insert(0, "Order Amount (Coins)")
def AmtFocusIn(event):
OrderAmt.config(foreground='black')
if OrderAmt.get() == 'Order Amount (Coins)':
OrderAmt.config(foreground='black')
OrderAmt.delete(0, END)
def AmtFocusOut(event):
if OrderAmt.get() == '':
OrderAmt.delete(0, END)
OrderAmt.config(foreground='gray')
OrderAmt.insert(0, 'Order Amount (Coins)')
OrderAmt.bind('<FocusIn>', AmtFocusIn)
OrderAmt.bind('<FocusOut>', AmtFocusOut)
OrderAmt.pack()
qty = OrderAmt.get()
#Percentage drop for bot to buy
PercentDrop = Entry(root, width=20, borderwidth=2, fg='gray')
PercentDrop.insert(0, "% Drop to Buy")
def PDFocusIn(event):
PercentDrop.config(foreground='black')
if PercentDrop.get() == '% Drop to Buy':
PercentDrop.config(foreground='black')
PercentDrop.delete(0, END)
def PDFocusOut(event):
if PercentDrop.get() == '':
PercentDrop.delete(0, END)
PercentDrop.config(foreground='gray')
PercentDrop.insert(0, '% Drop to Buy')
PercentDrop.bind('<FocusIn>', PDFocusIn)
PercentDrop.bind('<FocusOut>', PDFocusOut)
PercentDrop.pack()
#Percent gain to Sell
PercentRaise = Entry(root, width=20, borderwidth=2, fg='gray')
PercentRaise.insert(0, "% Raise to Sell")
def PRFocusIn(event):
PercentRaise.config(foreground='black')
if PercentRaise.get() == '% Raise to Sell':
PercentRaise.config(foreground='black')
PercentRaise.delete(0, END)
def PRFocusOut(event):
if PercentRaise.get() == '':
PercentRaise.delete(0, END)
PercentRaise.config(foreground='gray')
PercentRaise.insert(0, '% Raise to Sell')
PercentRaise.bind('<FocusIn>', PRFocusIn)
PercentRaise.bind('<FocusOut>', PRFocusOut)
PercentRaise.pack()
# Percent bottom out to sell - Failsafe to not lose money
PercentBottom = Entry(root, width=20, borderwidth=2, fg='gray')
PercentBottom.insert(0, "% Drop Failsafe")
def PBFocusIn(event):
PercentBottom.config(foreground='black')
if PercentBottom.get() == '% Drop Failsafe':
PercentBottom.config(foreground='black')
PercentBottom.delete(0, END)
def PBFocusOut(event):
if PercentBottom.get() == '':
PercentBottom.delete(0, END)
PercentBottom.config(foreground='gray')
PercentBottom.insert(0, '% Drop Failsafe')
PercentBottom.bind('<FocusIn>', PBFocusIn)
PercentBottom.bind('<FocusOut>', PBFocusOut)
PercentBottom.pack()
# Get account information
client = Client(api_key, api__secret, tld='us')
#print(client.get_account())
# Datastream via websocket
def getMinuteData(symbol, interval, lookback):
frame = pd.DataFrame(client.get_historical_klines(symbol, interval, lookback+' min ago EST'))
frame = frame.iloc[:, :6]
frame.columns = ['Time', 'Open', 'High', 'Low', 'Close', 'Volume']
frame = frame.set_index('Time')
frame.index = pd.to_datetime(frame.index, unit='ms')
frame = frame.astype(float)
return frame
test = getMinuteData('BTCUSDT', '1m', '30')
# Trading Strategy - Buy if asset fell by more than 0.2% withint the last 30 min
# Sell if asset rises by more than 0.15% or falls further by 0.15%
def strategyTest(symbol, qty, entered=False):
df = getMinuteData(symbol, '1m', '30')
cumulRet = (df.Open.pct_change() + 1).cumprod() -1
if not entered:
if cumulRet [-1] < -0.002:
order = client.create_order(symbol=symbol, side='BUY', type = 'MARKET', quantity=qty)
print(order)
entered = True
else:
print("No trade executed")
if entered:
while True:
df = getMinuteData(symbol, '1m', '30')
sinceBuy = df.loc[df.index > pd.to_datetime(order['transactTime'], unit='ms')]
if len(sinceBuy) > 0:
sinceBuyReturns = (sinceBuy.Open.pct_change() + 1).cumprod() -1
if sinceBuyReturns[-1] > 0.0015 or sinceBuyReturns[-1] < -0.0015:
order = client.create_order(symbol=symbol, side='SELL', type = 'MARKET', quantity=qty)
print(order)
break
def confirm():
sym = crypto.get()+'USDT'
qty = OrderAmt.get()
# Buttons
Confirm = tk.Button(root, text='Confirm?', padx=10, pady=5, fg = 'white', bg = 'black', command = lambda: confirm() )
Confirm.pack()
#Trade = tk.Button(root, text='Trade', padx=10, pady=10, fg='white', bg='black', command = lambda: strategyTest(sym, qty) )
Trade = tk.Button(root, text='Trade', padx=10, pady=5, fg='white', bg='black', command = lambda: print(sym) )
Trade.pack()
root.mainloop()```
Related
I want the code to get the last price and use it to divide the entered quantity (qty = "entered quantity" / "last price"). Finally, use the quantity to open a short or long order.I have a search bar and an input field for quantity. From the search bar, I can select all the USDT pairs available in Binance Futures. Currently #deneme field gets last price too but it's not working in the end.
from tkinter import *
from operator import truediv
import os
import tkinter
from pickle import TRUE
from tkinter import ttk
from tkinter import messagebox
from tkinter.messagebox import showinfo
from binance.client import Client
####API KEYS
api_key = os.environ.get('binance_api')
api_secret = os.environ.get('binance_secret')
client = Client(api_key, api_secret)
#Ekran
root= Tk()
root.geometry('300x300')
l = Label(root, text="MARKET ORDER")
l.config(font=("MARKET ORDER", 25))
l.pack()
#Bar
l = Label(root, text="Coin Girin")
l.config(font=("Coin Girin", 10))
l.pack()
lst = exchange_info = client.futures_exchange_info()
usdt_pairs = [s['symbol'] for s in exchange_info['symbols'] if 'USDT' in s['symbol']]
print(usdt_pairs)
def search(event):
value = event.widget.get()
if value == '':
combo_box['values'] = usdt_pairs
else:
data = []
for item in usdt_pairs:
if value.lower() in item.lower():
data.append(item)
combo_box['values'] = data
combo_box = ttk.Combobox(root,value=usdt_pairs)
combo_box.set('')
combo_box.pack()
combo_box.bind('<KeyRelease>', search)
#deneme
def show_ticker_info(event=None):
selected_symbol = combo_box.get()
ticker_info = client.futures_ticker(symbol=selected_symbol,timeframe='1m')
ticker_text.config(text=ticker_info['lastPrice'])
root.after(100, show_ticker_info) # update price every 100 milliseconds
ticker_text = Label(root, text="")
ticker_text.pack()
combo_box.bind("<<ComboboxSelected>>", show_ticker_info)
root.after(0, show_ticker_info) # start updating immediately
#qty girme
l = Label(root, text="Miktar Girin")
l.config(font=("Miktar Girin", 10))
l.pack()
qty_entry = Entry(root)
qty_entry.pack()
#Buton SAT
def buttonFunction():
qty = qty_entry.get()
selected_symbol = combo_box.get()
order = client.futures_create_order(symbol=selected_symbol,
side=Client.SIDE_SELL,
type=Client.ORDER_TYPE_MARKET,
leverage=20,
quantity=qty)
if order:
global pop
pop = Toplevel(root)
pop.title("SELL")
pop.geometry("250x150")
pop.config(bg="green")
pop_label = Label(pop, text="ORDER PLACED", bg="black", fg="white")
pop_label.pack(pady=10)
b = Button(root, text="SAT", bg="red", fg="white", command=buttonFunction)
b.config(font=("bas", 18))
b.pack(side=LEFT)
#Buton AL
def buttonFunction2():
selected_symbol = combo_box.get()
qty = qty_entry.get()
order = client.futures_create_order(symbol=selected_symbol,
side=Client.SIDE_BUY,
type=Client.ORDER_TYPE_MARKET,
leverage=20,
quantity=qty)
if order:
global pop
pop = Toplevel(root)
pop.title("BUY")
pop.geometry("250x150")
pop.config(bg="green")
pop_label = Label(pop, text="ORDER PLACED", bg="black", fg="white")
pop_label.pack(pady=10)
b2 = Button(root, text="AL", bg="green", fg="white", command=buttonFunction2,)
b2.config(font=("bas", 18))
b2.pack(side=RIGHT)
root.mainloop()
I cannot test your code. You can modify my example.
Snippet:
import locale
amount = 125000
# set locale to US
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
# format US currency value
US_dollar = locale.currency(amount, grouping=True)
print(US_dollar)
Result: $125,000.00
I am making a small project currency converter. When I convert USD to any other currency, it correctly displays the correct answer. If I choose another currency except for USD, the result comes as the same digit/amount as I put. But I want to convert entered currency into to_currency. How can I fix it?
# Import the modules needed
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
import requests
url = 'https://v6.exchangerate-api.com/v6/8a0fcd7df32ea4704f4fc48d/latest/USD'
response = requests.get(url)
response.raise_for_status()
data = response.json()
currency_key = data['conversion_rates']
def convert():
input_02.delete(0, END)
amount = input_01.get()
if amount == "":
messagebox.showinfo(title="Invalid", message="Please Insert the Amount")
return False
currency_02 = to_currency.get()
for i, j in currency_key.items():
var01 = i.upper()
var02 = currency_02.upper()
if var01 in var02:
try:
if from_currency.get() != 'USD':
amount = float(amount)/j
value = amount*j
input_02.insert(0, f"{value}")
else:
value = j*float(amount)
value = round(value, 4)
input_02.insert(0, f"{value}")
except ValueError:
messagebox.showinfo(title="Invalid", message="Please insert Amount in Digits")
window = Tk()
window.title('Currency Converter!')
window.iconbitmap('currency.ico')
window.config(padx=50, bg='#0CA7D3')
label_01 = Label(text="Currency Converter GUI", bg='#0CA7D3', foreground='white', font=("arial", 20, "bold"))
label_01.grid(column=0, row=0, columnspan=3, pady=15)
from_currency = StringVar()
from_currency.set(" USD ")
dropdown_01 = ttk.Combobox(textvariable=from_currency, width=16, font=("arial", 10, "bold"), state='enable',
values=list(currency_key))
dropdown_01.grid(column=0, row=1)
input_01 = Entry(font=("arial", 10, "bold"), width=19)
input_01.focus()
input_01.grid(column=0, row=2, pady=5)
to_currency = StringVar()
to_currency.set(" PKR ")
dropdown_02 = ttk.Combobox(textvariable=to_currency, width=16, font=("arial", 10, "bold"), state='readonly',
values=list(currency_key))
dropdown_02.grid(column=2, row=1)
input_02 = Entry(font=("arial", 10, "bold"), width=19)
input_02.grid(column=2, row=2, pady=5)
button = Button(text="Convert", command=convert, width=8, bg='#0084AB', fg='white', font=("arial", 10, "bold"))
button.grid(column=0, row=3, pady=20)
window.mainloop()
The rate for from_currency to to_currency can be calculated by:
rate = currency_key[to_currency.get()] / currency_key[from_currency.get()]
Below is the modified convert():
def convert():
amount = input_01.get().strip()
if amount == "":
messagebox.showinfo(title="Invalid", message="Please insert the amount")
return False
try:
rate = currency_key[to_currency.get()] / currency_key[from_currency.get()]
value = float(amount) * rate
input_02.delete(0, "end")
input_02.insert("end", value)
except ValueError:
messagebox.showinfo(title="Invalid", message="Please insert amount in digits")
I have not tried to run the code, but looking at this:
amount = float(amount)/j
value = amount*j
input_02.insert(0, f"{value}")
You are multiplying and dividing amount by j, so the final value is equal to the initial amount.
As a side note, I would try to use variable names which are a little bit more descriptive.
I have two issues.
One:
I can't figure out how to calculate days left until a specific date which the user inputs in a calendar interface.
Secondly:
I want to use the numbers that the user has input in the interface to do some calculations with, and to watch what is going on I print some of the input to the terminal - however, the .value attribute returns "0" and I don't understand why.
Below the #PROXIMITY comment in the code you will find the calendar/date. I just want to subtract the date today from the date specified by the user in the calendar interface and output the days left.
Below the #VALUE is the calculation that prints "0" when i print the .value attribute.
Full code:
from tkcalendar import * # Calendar module
import tkinter.messagebox # Import the messagebox module
import datetime
import pickle
task_list = []
task_types = ['Sparetime', 'School', 'Work']
class Task:
def __init__(self, n, type_, i, m, p, h, v): #(w=8, p, u, n, v):
self.name = n
self.type = type_
self.impact = i
self.manageability = m
self.proximity = p
self.hours = h
self.value = v
#self.connectivity = c
##self.work = w ##hours of work per day
##self.urgency = u
##self.note = n
##self.value = v
def show_tasks():
# DELETED: for task in task_list:
# REPLACED WITH: task = task_list[-1]
task = task_list[-1]
#print(
#'Task:'+task.name + '\n' +
#'Impact:' + task.impact + '\n' +
#'Manageability:' + task.manageability + '\n' +
#'Hours:' + task.hours + '\n'
#'Value:' + task.value +'\n'
#)
print('Task:')
print(task.name)
print('\n')
print('Impact:')
print(task.impact)
print('\n')
print('manageability:')
print(task.manageability)
print('\n')
print('Hours')
print(task.hours)
print('\n')
print('Value:')
print(task.value)
def open_add_task():
taskwin = Toplevel(root)
taskwin.focus_force()
#TITLE
titlelabel = Label(taskwin, text='Title task concisely:', font=('Roboto',11,'bold')).grid(column=1, row=0)
name_entry = Entry(taskwin, width=40, justify='center')
name_entry.grid(column=1, row=1)
#TYPE
typelabel = Label(taskwin, text='Type', font=('Roboto',10)).grid(column=0, row=2)
type_var = StringVar(value=task_types[0])
OptionMenu(taskwin, type_var, *task_types).grid(column=0, row=3, sticky='nsew')
#IMPACT
impactlabel = Label(taskwin, text='Impact', font=('Roboto',10)).grid(column=1, row=2)
imp_var = StringVar(value=0)
OptionMenu(taskwin, imp_var, *range(0, 10+1)).grid(column=1, row=3, sticky='ns')
#MANAGEABILITY
manlabel = Label(taskwin, text='Manageability', font=('Roboto',10)).grid(column=2, row=2)
man_var = StringVar(value=0)
OptionMenu(taskwin, man_var, *range(0, 10+1)).grid(column=2, row=3, sticky='nsew')
#PROXIMITY
proximity_label = Label(taskwin, text = 'Choose a deadline', font=('Roboto',10), justify='center')
proximity_label.grid(column=1, row=4)
cal = Calendar(taskwin, selectmode='day', year=2021, month=4, day=27)
cal.grid(column=1, row=5)
def get_date():
proximity_output_date.config(text=cal.get_date()) ##the .config didn't work until i did .grid(column=, row=) on seperate lines
#HOURS(required)
hourlabel = Label(taskwin, text='Whole hours \n required', font=('Roboto',10)).grid(column=1, row=16)
hour_entry = Entry(taskwin, width=4, justify='center')
hour_entry.grid(column=1, row=17)
#CONNECTIVITY
#for index, task in enumerate(task_list):
#Checkbutton(taskwin, **options).grid(column=0, row=index)
C_lab = Label(taskwin,text="Check tasks this task is related to").grid(column=1, row=18)
placement=19
for task in task_list:
Checkbutton(taskwin, text=(task.name)).grid(column=1, row=placement, sticky="w")
placement+=1
#VALUE
val_var = (int(imp_var.get()))+ (int(man_var.get()))
def add_task():
if name_entry.get() != '': # If textbox inputfield is NOT empty do this:
task_list.append(Task(name_entry.get(), type_var.get(), imp_var.get(), man_var.get(), cal.get_date(), hour_entry.get(), val_var))
show_tasks()
listbox_tasks.insert(tkinter.END, name_entry.get())
name_entry.delete(0, tkinter.END)
taskwin.destroy()
else:
tkinter.messagebox.showwarning(title='Whoops', message='You must enter a task')
next_button = Button(taskwin, text='Next', font=('Roboto',10), command=add_task).grid(column=2, row=placement, sticky="e")
placement+=1
def sort_tasks():
pass
def delete_task():
try:
task_index = listbox_tasks.curselection()[0]
listbox_tasks.delete(task_index)
except:
tkinter.messagebox.showwarning(title='Error', message='You must select a task to delete')
def save_tasks():
pass
#tasks = listbox_tasks.get(0, listbox_tasks.size())
#pickle.dump(tasks, open('tasks.dat', 'wb'))
root = Tk()
task_frame = Frame()
# Create UI
your_tasks_label = Label(root, text='THESE ARE YOUR TASKS:', font=('Roboto',10, 'bold'), justify='center')
your_tasks_label.pack()
scrollbar_tasks = tkinter.Scrollbar(root)
scrollbar_tasks.pack(side=tkinter.RIGHT, fill=tkinter.Y)
listbox_tasks = tkinter.Listbox(root, height=10, width=50, font=('Roboto',10), justify='center') # tkinter.Listbox(where it should go, height=x, width=xx)
listbox_tasks.pack()
listbox_tasks.config(yscrollcommand=scrollbar_tasks.set)
scrollbar_tasks.config(command=listbox_tasks.yview)
try:
#tasks = pickle.load(open('tasks.dat', 'rb'))
listbox_tasks.delete(0, tkinter.END)
for task in task_list:
listbox_tasks.insert(tkinter.END, task)
except:
tkinter.messagebox.showwarning(title='Phew', message='You have no tasks')
#BUTTONS
Add_Button = Button(root, text='Add New', width=42, command=open_add_task)
Add_Button.pack()
button_delete_task = Button(root, text='Delete task', width=42, command=delete_task)
button_delete_task.pack()
button_save_tasks = Button(root, text='Save tasks', width=42, command=save_tasks)
button_save_tasks.pack()
#sort_type = StringVar(value='All')
#OptionMenu(btn_frame, sort_type, 'All', *task_types).grid(column=0, row=0, sticky='nsew')
#sort_imp = StringVar(value='Any')
#OptionMenu(btn_frame, sort_imp,'Any', *range(0, 10+1)).grid(column=1, row=0, sticky='nsew')
#Button(btn_frame, text='Sort', command=sort_tasks).grid(column=1, row=1, sticky='nsew')
root.mainloop()
how to calculate days left until a specific date
You might subtract datetime.date from datetime.date to get datetime.timedelta object holding numbers of days, consider following example
import datetime
d1 = datetime.date(2021, 1, 1) # year, month, day
d2 = datetime.date(2021, 1, 10)
diff21 = (d2-d1).days
diff12 = (d1-d2).days
print(diff21)
print(diff12)
output
9
-9
For getting current date you might use datetime.date.today().
For your first issue, you can use cal.selection_get() to return the selected date in datetime.date type. Then you can calculate the days left easily:
selected = cal.selection_get()
delta = (selected - datetime.date.today()).days
status = "overdue" if delta <= 0 else f"{delta} days left"
print(f"{selected} ({status})")
For second issue, you need to move the line val_var = (int(imp_var.get()))+ (int(man_var.get())) into add_task() function:
def add_task():
if name_entry.get() != '':
val_var = int(imp_var.get()) + int(man_var.get())
...
else:
...
Note that you need to do some validations on the values returned by imp_var.get() and man_var.get() to avoid exception due to invalid values.
I have just started utilizing Python's tkinter module to create some basic GUIs. 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). 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)'
User then selects Mars US which should show something like 'Last Update: (2 Days Delay)'
Problem: The labels overlap each other as shown in this photo EXAMPLE PHOTO
Any solution to this?
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.
Example:
price_str = StringVar()
prica_label = Label(root, textvariable=price_str).pack()
price_str.set("new price")
Clearing Label Text:
as jasonharper said. Use label.config(text="something")
The following script shows an example, where a label is dynamically incremented by 1 until the stop button is pressed:
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
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()
After testing out many times and reading Stackoverflow for several hours, I decided to right this question. My Text (part of the bigger code) is below:
import pandas as pd
import datetime as dt
from tkinter import *
import tkinter.filedialog
from tkinter import messagebox
def test_click():
global ipt_dt
global coef
global z
global w
z = item_prosp['Accrual_Start'].min()
w = item_prosp['Accrual_End'].max()
ipt_d = tkvar_d.get()
ipt_m = tkvar_m.get()
ipt_y = tkvar_y.get()
x = 0
while x == 0:
ipt = str(ipt_d + '/'+ ipt_m + '/' + ipt_y)
try:
ipt_dt = dt.datetime.strptime(ipt, "%d/%b/%Y")
if ipt_dt < z or ipt_dt > w:
messagebox.showinfo("Error", "The input date is outside scope date")
else:
print("Date ok")
x =+ 1
except:
messagebox.showerror("Error", "The input date is not valid")
ipt_d = 0
ipt_m = 0
ipt_y = 0
continue
And the tkinter section of the code that generate the inputs is:
#Question 1 - Evaluation date
label4 = Label(window, text='Please inform the valuation date :', bg='white').grid(row=13, column=0, columnspan=3, pady=2, sticky=W)
tkvar_d = StringVar(window)
tkvar_m = StringVar(window)
tkvar_y = StringVar(window)
choices_d = ['1', '2', '3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31']
choices_m = ['Jan', 'Feb', 'Mar','Apr','May','Jun','Jul','Aug','Sep','Oct', 'Nov', 'Dec']
choices_y = ['2018','2019', '2020', '2021','2022','2023','2024','2025','2026','2027','2028','2029','2030']
popupmenu_d = OptionMenu(window, tkvar_d, *choices_d)
popupmenu_m = OptionMenu(window, tkvar_m, *choices_m)
popupmenu_y = OptionMenu(window, tkvar_y, *choices_y)
label5 = Label(window, text='Day :', bg='white').grid(row=14, column=0, sticky=E+W)
popupmenu_d.grid(row=15, column=0, padx=2, sticky=E+W)
label6 = Label(window, text='Month :', bg='white').grid(row=14, column=1, sticky=E+W)
popupmenu_m.grid(row=15, column=1, padx=2, sticky=E+W)
label7 = Label(window, text='Year :', bg='white').grid(row=14, column=2, sticky=E+W)
popupmenu_y.grid(row=15, column=2, padx=2, sticky=E+W)
Button(window, text="Test Date", width=10, command=test_click).grid(row=15, column=3, padx=5, pady=10, sticky=W)
The sample value for W when the file is run is:
2018-04-18 00:00:00
and for Z is:
2018-04-18 00:00:00
My need is to import a file (externally built and already structured), read 2 values from it (variables Z and W in the code) and compare it with an input variable (ipt_dt) which is a date filled in by the user through 3 dropdown menus from tkinter.
The error is that the try is not going through the if statement and it never prints out if the input is outside the scope date. Everytime I enter a date smaller than the minimum date or higher than the maximum date it returns the showerror message eventhou it pritns the "Date ok".
Anyone has any idea on how to solve this or why my fi is being ignored?
Thanks!
I looked at your originally posted code and you load the Excel into a df with the load_click function. But you don't actually run the load_click function anywhere, so the dataframe isn't loaded and so z and w aren't filled.
If you change the click1() function as follows, then it should work (it did for me with some sample data).
def click1():
global a
a = tkinter.filedialog.askopenfilename(initialdir = "/",title = "Select file", filetypes = ( ("Excel file", "*.xlsx"), ("All files", "*.*") ) )
output1.insert(END, a)
global a1
a1 = output1.get()
load_click()
Or add a seperate 'load' button if you want (at the bottom of the #File1 part):
Button(window, text="Load", width=6, command=load_click).grid(row=4, column=3, padx=5, sticky=W)
You might also want to add another x = 1 in the if-statement. Otherwise the messagebox will keep popping up due to the while loop, making it impossible to correct the input date.
x = 0
while x == 0:
ipt = str(ipt_d + '/'+ ipt_m + '/' + ipt_y)
try:
ipt_dt = dt.datetime.strptime(ipt, "%d/%b/%Y")
print type(ipt_dt)
if (ipt_dt < z) or (ipt_dt > w):
messagebox.showinfo("Error", "The input date is outside scope date")
x = 1 # I've added this one
else:
print("Date ok")
x =+ 1
except:
messagebox.showerror("Error", "The input date is not valid")
ipt_d = 0
ipt_m = 0
ipt_y = 0
continue