I would like to use widgets.Text() to specify multiple variables (year, month, day) that can be passed into an API request.
Based on the answer to this question I am able to successfully save the input from a single text box to a single variable. But I would like to display multiple text boxes at the same time and save their input values to three different output variables. I'm unsure how to generalize from the example given.
This code works for a single variable:
# Create text widget for output
year_output = widgets.Text()
# Create text widget for input
year_input = widgets.Text(
placeholder="example '2017'",
description='Year:',
disabled=False
)
# Define function to bind value of the input to the output variable
def bind_input_to_output(sender):
year_output.value = year_input.value
# Tell the text input widget to call bind_input_to_output() on submit
year_input.on_submit(bind_input_to_output)
# Display input text box widget for input
display(year_input)
I would like to be able to do something like this, as efficiently as possible:
year_output = widgets.Text()
month_output = widgets.Text()
day_output = widgets.Text()
year_input = widgets.Text(
placeholder="example '2017'",
description='Year:',
disabled=False
)
month_input = widgets.Text(
placeholder="example '04'",
description='Month:',
disabled=False
)
day_input = widgets.Text(
placeholder="example '30'",
description='Day:',
disabled=False
)
#make this a generic function so that I don't have to repeat it for every input/output pair
def bind_input_to_output(sender): #what is 'sender'?
output_var.value = input_var.value
year_input.on_submit(bind_input_to_output)
mont_input.on_submit(bind_input_to_output)
day_input.on_submit(bind_input_to_output)
display(year_input)
display(month_input)
display(day_input)
Apologies if this isn't clear enough! I can clarify as needed. Any guidance is greatly appreciated. Thank you!
I was able to do what I wanted by adapting the instructions from this question. My code is below, for reference:
import ipywidgets as widgets
from IPython.display import display
class date_input():
def __init__(self,
year = "e.g. '2017'",
month = "e.g. '05'",
day = "e.g. '21'"
):
self.year = widgets.Text(description = 'Year',value = year)
self.month = widgets.Text(description = 'Month',value = month)
self.day = widgets.Text(description = 'Day',value = day)
self.year.on_submit(self.handle_submit)
self.year.on_submit(self.handle_submit)
self.year.on_submit(self.handle_submit)
display(self.year, self.month, self.day)
def handle_submit(self, text):
self.v = text.value
return self.v
print("enter the year, month and day above, then press return in any field")
f = date_input()
To view the output, in the next cell run:
print("Date input captured: " + "/".join([f.year.value, f.month.value, f.day.value]))
Related
def in_Vals():
in_win = Tk()
in_win.title("Check In Details")
in_win.geometry("700x700")
in_win.resizable(0,0)
# title
title = Label(in_win,text="Check In Details",font=("Harlow Solid Italic",30,"italic"),fg="black",bg="#fbb08c")
title.pack(anchor="center",pady=5)
#creating label's
_Id_ = Label(in_win,text="Id :",font=("Times New Roman",15,"italic"),fg="black",bg="#fbb08c")
_Name_ = Label(in_win,text="Name :",font=("Times New Roman",15,"italic"),fg="black",bg="#fbb08c")
_Date_ = Label(in_win,text="Date :",font=("Times New Roman",15,"italic"),fg="black",bg="#fbb08c")
_Time_ = Label(in_win,text="Time :",font=("Times New Roman",15,"italic"),fg="black",bg="#fbb08c")
_Number_ = Label(in_win,text="Number :",font=("Times New Roman",15,"italic"),fg="black",bg="#fbb08c")
_Id_.pack(anchor='w',padx=10,pady=20)
_Name_.pack(anchor='w',padx=10,pady=20)
_Date_.pack(anchor='w',padx=10,pady=20)
_Time_.pack(anchor='w',padx=10,pady=20)
_Number_.pack(anchor='w',padx=10,pady=20)
# creating submit function
def submit():
print(f"{in_val_1}\n{in_val_2}\n{in_val_3}\n{in_val_4}\n{in_val_5}")
# creating entries
Id = Entry(in_win,width=25,font=("Courier",15,'bold'))
Name = Entry(in_win,width=25,font=("Courier",15,'bold'))
Date = Entry(in_win,width=25,font=("Courier",15,'bold'))
Time = Entry(in_win,width=25,font=("Courier",15,'bold'))
Number = Entry(in_win,width=25,font=("Courier",15,'bold'))
Id.place(x=100,y=87)
Name.place(x=100,y=157)
Date.place(x=100,y=227)
Time.place(x=100,y=293)
Number.place(x=100,y=360)
#getting values
in_val_1 = Id.get()
in_val_2 = Name.get()
in_val_3 = Date.get()
in_val_4 = Time.get()
in_val_5 = Number.get()
# creating submit button
submit = Button(in_win,text="Submit",font=("Wild Latin",15,"bold"),command=submit)
submit.place(x = 250,y=450)
in_win.config(bg="#fbb08c")
in_win.mainloop()
Here the function in_vals() is a coded to take data from the ID, Name, Date, Time, Number Entries and assign the values of The entries to the variables in_val_1 to in_val_5 ,to get the values from the entry box I have used the .get() Method. but when I try to Print the Variables that I assigned to the .get() method, it prints some white Space's.
The solution for the problem same as mine is
defining the values outside the the button function does not get anything.
here I have defined out side the button function
after defining it inside the button function it gives me the desired output
I use a GUI for some web automation with selenium.
I have several comboboxes (will do one example here)
This is my example code:
app = Tk()
def callback(*args): # should get the updated values in Combobox ?
global v_sv_league
v_sv_league = str(sv_league.get())
#List to be filled by scraper
li_leagues = []
#StringVar
sv_league = StringVar()
sv_league.trace("w", callback)
#Label
l_d_league = tk.Label(app,text='League:',bg='#1d1b29', fg='#f8f09d',font='Tahoma 10')
#Combobox
d_league = ttk.Combobox(app,textvariable=sv_league,values=li_leagues)
#Scrape
def scrape():
btn_tflist = wait.until(EC.element_to_be_clickable((By.XPATH,('/html/body/main/section/nav/button[3]'))))
btn_tflist.click()
btn_tf_filters = wait.until(EC.element_to_be_clickable((By.XPATH,'/html/body/main/section/section/div[2]/div/div/div[2]/div[2]')))
btn_tf_filters.click()
bol_scrape = True
if bol_scrape is True:
print('\n Start scraping... this might take a few minutes. Please wait and dont press anything until trade_buddy is done!\n')
li_leagues = []
print('Getting leagues...\n')
league_dropdown_menu = wait.until(EC.element_to_be_clickable((By.XPATH,('/html/body/main/section/section/div[2]/div/div[2]/div/div[1]/div[1]/div[7]/div'))))
league_dropdown_menu.click()
time.sleep(1)
# scrape all text
scrape_leagues = driver.find_elements_by_xpath("//li[#class='with-icon' and contains(text(), '')]")
for league in scrape_leagues:
export_league = league.text
export_league = str(export_league)
export_league = export_league.replace(',', '')
li_leagues.append(export_league)
app.mainloop()
So basically this is just a small part of my code but this is what I got for one of my combobox's.
You can see that I will call for def scrape at some point in my code to scrape data and to fill my list li_leagues.
However, my combobox is not refreshing the content and stays empty.
For OptionMenu I got it set up (with a it other code) but I cant get it working with combobox.
Any advice what I am missing here?
Thanks a slot!
Try using this line of code, after appending the list with values.
.....
export_league = export_league.replace(',', '')
li_leagues.append(export_league)
c_league.config(values=li_leagues)
config() method acts as a updater that just updates your widget, when called.
Hope it was of some help.
Cheers
I am trying to make a simple program that gets information off an API and displays it on python GUI with tkinter.
So far I have been able to do this but a new challenge is getting the information collected from the API to refresh every hour.
Basically I need the data() function to be re-run every hour so that the information on the GUI updates.
from tkinter import *
import requests
def data():
url = requests.get("https://stats.foldingathome.org/api/donor/PointofHorizon")
json = str((url.json()))
i = json.count(',')
data = json.split(",")
score = data[i]
score = score.replace(" 'credit': ","")
score = score.replace("}","")
unit = data[0]
unit = unit.replace("{'wus': ","")
scores = Label(app, text = score)
units = Label(app, text = unit)
scores.pack()
units.pack()
app = Tk()
app.geometry("500x200")
title = Label(app,text = "Folding Score")
title.pack()
I have looked around and haven't been able to find a way that works for me, would be amazing if someone could point me in the right direction. I'm still learning and all.
I think what you're looking for is the after method in tkinter. I changed the data function to refresh data on the widgets. I moved the code that created the labels to be outside of the refresh_data function. Once the widgets were created, I called the refresh_data function to put information on the widgets. This function would tell tkinter to wait an hour before running it again which created a loop.
from tkinter import *
import requests
def refresh_data():
url = requests.get("https://stats.foldingathome.org/api/donor/PointofHorizon")
json = str((url.json()))
i = json.count(',')
data = json.split(",")
score = data[i]
score = score.replace(" 'credit': ","")
score = score.replace("}","")
unit = data[0]
unit = unit.replace("{'wus': ","")
scores.config(text=score)
units.config(text=unit)
app.after(3600000, refresh_data) #3600000 milliseconds in an hour
app = Tk()
app.geometry("500x200")
title = Label(app,text = "Folding Score")
title.pack()
scores = Label(app)
units = Label(app)
scores.pack()
units.pack()
refresh_data()
app.mainloop()
I am trying to create a loop that will display each title of product for their individual labels (Tkinter module).
With the current loop i can get it to print my 10 "static_webpage_1_titles" in the list, but i am wanting to also increase the variable Label_1 by +1 increment each time.
For example, it should do somthing like this:
Label_1['text'] = static_webpage_1_titles[0]
Label_2['text'] = static_webpage_1_titles[1]
Label_3['text'] = static_webpage_1_titles[2]
Here is my current code:
def Generate_Product_Name_and_Price_1():
if Button_on:
Find_static_webpage_1()
for i in range(len(static_webpage_1_titles)):
Label_1['text'] = static_webpage_1_titles[i]
EDIT:
product_labels = [Label_1['text'], Label_2['text'], Label_3['text'],
Label_4['text'], Label_5['text'], Label_6['text'],
Label_7['text'], Label_8['text'], Label_9['text'],
Label_10['text']]
I have created a list above with each label widget and changed the last line of code in my loop to:
def Generate_Product_Name_and_Price_1():
if Button_on:
Find_static_webpage_1()
for i in range(len(static_webpage_1_titles)):
product_labels[i] = static_webpage_1_titles[i] +': $'+ static_webpage_1_price[i]
When i run this, i do not receive any IDLE error but my label widgets do not get populated with data.
You need to make a list of the Label instances, not the text attributes of Label instances. Like this:
product_labels = [Label_1, Label_2, Label_3,
Label_4, Label_5, Label_6,
Label_7, Label_8, Label_9,
Label_10]
Then you access the attribute like this:
for i in range(len(static_webpage_1_titles)):
product_labels[i]['text'] = static_webpage_1_titles[i] +': $'+ static_webpage_1_price[i]
You could also make this a little neater with zip():
for label, title, price in zip(product_labels, static_webpage_1_titles, static_webpage_1_price):
label['text'] = title +': $'+ price
I’ve got a QTableView based on a QSqlTableModel.
I want to filter displayed information: a user chooses one year in a combobox, and one or more perons in a multiple choices list. The QTableView data is filtered by these two widgets. My problem is that the data is correctly filtered on year, but only on the first personn selected. Other people's data are not displayed.
This is the code which creates the widget and the model, fills it, and filters it to display information in the QTableView :
self.model = QtSql.QSqlTableModel(self, self.db)
self.model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
self.ui.tbv_suivtemp.setModel(self.model)
self.model.setTable("bdsuivis.t_suivprev_tablo")
self.model.select()
self.model.setHeaderData(22, QtCore.Qt.Horizontal, "Annee")
self.model.setHeaderData(21, QtCore.Qt.Horizontal, "Salarie")
annee = self.ui.cbx_channee.itemText(self.ui.cbx_channee.currentIndex())
if len(annee) == 0 and len(self.text_sal) == 0:
self.model.setFilter("")
else:
filtre = "annee = '%s' AND salaries IN ('%s')" % (annee, self.text_sal)
print filtre
self.model.setFilter(filtre)
This is the code to create self.text_sal:
def choisal(self):
list_sal = []
for item in xrange (len(self.ui.lst_salaries.selectedItems())):
salarie = self.ui.lst_salaries.selectedItems()[item].text().replace("\'","\'\'")
list_sal.append(salarie)
self.text_sal = ", ".join((str(x) for x in list_sal)).replace(",","\',\'")
print filtre gives :
annee = '2014' AND salaries IN ('Dupont Albert','Durant Hector')
Which represents the WHERE clause from a SQL query.
My problem is: the year is correctly filtered, but only for "Albert Dupont" - the data for "Hector Durant" is not displayed. If, as a user, I click for the first time on "Hector Durand", in my multiple choices list, then on "Albert Dupont", the data for "Hector Durand" in 2014 is displayed.
Is this normal behaviour for a QSqlTableModel filter? Is there a way to obtain data for the two persons?