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))
Related
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
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!
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 send selected values from radiobuttons into a .docx file
importing what I need, focus is on docx
import tkinter as tk
from docx import Document
main = tk.Tk()
these are my options that I need to place into a word document on the left of the table, they act as questions in a survey.
info = ["option 1", "option 2", "option 3", "option 4"
]
Here I am placing radiobuttons called Yes, No & N/A which are answers to the options on the left(list of info above) and also Label to represent options or in other words questions..
vars = []
for idx,i in enumerate(info):
var = tk.IntVar(value=0)
vars.append(var)
lblOption = tk.Label(main,text=i)
btnYes = tk.Radiobutton(main, text="Yes", variable=var, value=2)
btnNo = tk.Radiobutton(main, text="No", variable=var, value=1)
btnNa = tk.Radiobutton(main, text="N/A", variable=var,value=0)
lblOption.grid(column=0,row=idx)
btnYes.grid(column=1,row=idx)
btnNo.grid(column=2,row=idx)
btnNa.grid(column=3,row=idx)
Here is my function, creating a document and saving is the easy part. My issue is that I am muddled up creating a table that will have; Options on the left (from info) at the top are the headers (see RadioButtons yes, no, & N/a). And selected data, as an example, if for option 1 I have selected No, then save the data into a .docx file with the one been selected (See example bottom of page at Desired output).
def send():
document = Document()
section = document.sections[0]
#add table
table = document.add_table(1, 4)
#style table
table.style = 'Table Grid'
#table data retrived from Radiobuttons
items = vars.get()
#populate header row
heading_cells = table.rows[0].cells
heading_cells[0].text = "Options"
heading_cells[1].text = btnYes.cget("text")
heading_cells[2].text = btnNo.cget("text")
heading_cells[3].text = btnNa.cget("text")
for item in items:
cells = table.add_row().cells
cells[0].text = #Options
cells[1].text = #Yes values
cells[2].text = #No values
cells[3].text = #N/A values
#save doc
document.save("test.docx")
#button to send data to docx file
btn = tk.Button(main, text="Send to File", command= send)
btn.grid()
main.mainloop()
this is what it opens up:
Here is the desired output:
Number 1 represents selected items from the tkinter application. But will figure out how to change it to a tick box.
I am kinda confused where I am at, I am new using docx.. been trying to read the documentation.. and this is where I digged my self a hole into.
In your current code, vars is a list of IntVars. You want to get each value individually instead of vars.get(). Also when writing to docx file, you need both info and values of radiobuttons, to track them both you can use an index.
With minimal changes to your code, you can use something like this.
def send():
...
...
heading_cells[3].text = btnNa.cget("text")
for idx, item in enumerate(vars):
cells = table.add_row().cells
cells[0].text = info[idx] # gets the option name
val = item.get() #radiobutton value
if val == 2: # checks if yes
cells[1].text = "1"
elif val == 1: # checks if no
cells[2].text = "1"
elif val == 0: # checks if N/A
cells[3].text = "1"
#save doc
document.save("test.docx")
or you can use a dictionary to map radiobuttons to cells.
valuesCells = {0: 3, 1: 2, 2: 1} # value of radiobutton: cell to write
# hard to read what's going on though
for idx, item in enumerate(vars):
cells = table.add_row().cells
cells[0].text = info[idx] # gets the option name
val = item.get()
cells[valuesCells[val]].text = "1"
#save doc
document.save("test.docx")
Currently with the below code I seem to be getting a weird issue as well cant seem to get the value of refreshtoken when I click the submit button. I do get the print for word but for refreshtoken I receive .!entry in the Console.
def getCommand(r):
print('word')
print(r)
tokenWindowFrame = Tk()
tokenWindowFrame.title("Add Character")
refreshLabel = ttk.Label(tokenWindowFrame, text="Refresh Token : ")
refreshLabel.grid(row=1,column=1)
refreshToken = ttk.Entry(tokenWindowFrame, width = 50)
refreshToken.grid(row=1,column=2)
button = ttk.Button(tokenWindowFrame, text = "Submit", command=lambda
r=refreshToken: getCommand(r))
button.grid(row=3,column=2)
tokenWindowFrame.mainloop()
You can't print an entry object, you need to print the text in the entry object. Use:
refreshToken.get()
I ended up having to change this line
button = ttk.Button(tokenWindowFrame, text = "Submit", command=lambda r=refreshToken: getCommand(r))
To :
button = ttk.Button(tokenWindowFrame, text = "Submit", command=lambda r=refreshToken: getCommand(r.get()))
The r.get() is what I was missing. As both print(r.get()) would not work in the Function.
To get the text in an entry box you need:
<entry_box>.get()
If you are trying to print it then you could just do:
print(<entry_box>.get())
Or in your case:
print(r.get())
Hope this works for you!