Python ttk combobox value update? - python

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

Related

How to not display duplicates in a list using tkinter

How do I get this program to not display the same selection again to the user when its already been selected ?
I know behind the scenes I can create a set of my entries for the code to continue using, but I cant seem to stop the display showing duplicate items if the user selects the same thing again. I thought the 'not in' statement might have worked. Any help please ?
from tkinter import *
from tkinter import ttk
root = Tk()
# set in pixels
root.geometry("1000x750+100+100")
my_list = set()
def combo_click(event):
my_label = Label(root, text=myCombo.get()).pack()
if myCombo.get() not in my_list:
my_list.add(myCombo.get())
# print('List without duplicate items (Set) ' + '\n')
OptionList = [
"Aries",
"Taurus",
"Gemini",
"Cancer"
]
clicked = StringVar()
clicked.set(OptionList[0])
# *Options - https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists
#drop = OptionMenu(root, clicked, *OptionList, command=selected)
#drop.pack(pady=100)
myCombo = ttk.Combobox(root, value=OptionList)
myCombo.current(0)
myCombo.bind("<<ComboboxSelected>>", combo_click)
myCombo.pack()
root.mainloop()
A method you could use to filter out duplicates in a list is the following code. I am assuming you are adding each bit of text to the Tkinter list through variables.
In my code the variable: a is the item we wish to add to the list.
Code to filter through entries to a Tkinter list:
While True: #replace the bit inbetween w and t with your how long you want to do it
#add everything you add to a list before you add to Tkinter Listbox as shown below.
for x in tlist:
if tlist contains a:
print("Duplicate! This will not be added.")
else:
[whatever_you_called_your_listbox].insert(END,a)
print(a,"Was added.")
Hope this helps!

How to refresh a function every hour in tkinter?

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

Is there a way to get the Column menu updates automatically with the sheet menu?

I am devoloping an app where the user upload his excel file and gets the Sheets and columns. How do I get the Columns drop-down menu (The second one) to update with the Sheets drop-down menu(First one).
I have already tried to make a function 'Update' that gets the new sheet form the Fuction 'GetSheet' and update it. But it does not work as the column drop-down menu get Always stucked in the Default sheet.
master.title('ATT Analytics App')
master.geometry("400x250")
Myfile= filedialog.askopenfile()
wb = load_workbook(filename = str(Myfile.name))
#Sheets = wb.sheetnames
variable = StringVar(master)
variable.set(str(wb.sheetnames[2])) # default value
w = OptionMenu(master, variable, str(wb.sheetnames[0]), str(wb.sheetnames[1]), str(wb.sheetnames[2]), str(wb.sheetnames[3]))
w.pack()
def GetSheet():
FileRead = pd.read_excel(str(Myfile.name),sheet_name= str(variable.get()))
MyHeadres = list(FileRead.columns.values)
return MyHeadres, FileRead
variable1 = StringVar(master)
def Update(TheHeaders):
variable1.set(str(TheHeaders[0]))
wc = OptionMenu(master, variable1, str(TheHeaders[0]), str(TheHeaders[1]), str(TheHeaders[2]), str(TheHeaders[3]), str(TheHeaders[4]), str(TheHeaders[5]))
return wc
def RunAll():
GetMySheet, FileRead = GetSheet()
UpdateMysheet = Update(GetMySheet)
return UpdateMysheet, variable1.get(), FileRead
button = Button(master, text="Run", command=RunAll)
button.pack(side = TOP)
UpdateMysheet, MyColumn, ReadMyFile = RunAll()
UpdateMysheet.pack()
FileRead = ReadMyFile
mainloop()
I want to bring my Code to be able to update the Column Drop-down (Variable1) menu with the drop down menu (Variable), which works fine and also get to store the column you want and move on the choose another one and so on..
I would appreciate your help a lot.
Edit: Now when I choose another sheet, the Default value of the columns updates to the new sheet, but when I look the complete List, I find out that the values are from the old sheet.

Python looping for label variables

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

Pprint within tkinter

I'm trying to find a way to show a list of titles, urls, and time stamps for a google search/RSS FEED that I'm working on for a GUI. I'm having a lot of trouble trying to find a way to sort the results in a nice readable form. Any articles or guidance as far as what to do would be greatly appreciated!
from tkinter import *
import urllib.request
import feedparser
from pprint import pprint
search_term = ('') #search term for url
quoted_search_term = urllib.parse.quote(search_term)
def go():
text.delete(1.0, END) #delete text
rss_string = 'https://news.google.com/news/section?output=rss'.format (quoted_search_term)
parsed_rss_string = feedparser.parse(rss_string) #assigning variable for parsed feed
text.insert(1.0, parsed_rss_string) #insert text of parsed feed
browser_window = Tk() #tk window
browser_window.title('RSS Feed') #Window title
label = Label(browser_window, text= 'Search:')
entry = Entry(browser_window)
button = Button(browser_window, text='Go', command = go)#Go Button
text = Text(browser_window) #results box
label.pack(side=TOP) #Positioning of search title
entry.pack(side=TOP) #Positioning of search box
button.pack(side=TOP)#Positioning of go
text.pack(side= RIGHT) #Positioning of text
browser_window.mainloop()
To prettified string, use pprint.pformat:
from pprint import pformat
...
def go():
...
parsed = feedparser.parse(rss_string)
prettified = pformat(parsed)
text.insert("1.0", prettified)
NOTE:
there's no placeholder in the url https://news.google.com/news/section?output=rss; no effect of str.format.
feedparser.parse does not return a string, but a dictionary.
UPDATE to show publish date, title, url only, you need to get those entries from dictionaries:
def go():
rss_string = 'https://news.google.com/news/section?output=rss'
parsed = feedparser.parse(rss_string)
text.delete("1.0", END)
for entry in parsed['entries']:
text.insert(END, '{0[published]} - {0[title]} {0[link]}\n\n'.format(entry))

Categories