Create buttons in loop with different actions - Python - python

I am working on Dynamo for Revit. My code takes sheet numbers and other info, then creates labels and buttons for each IN element with a for loop. The GUI works fine and I have all the elements in place, but how do I tell each individual button to open a different sheet? See screenshot.
I need to understand the workflow, but here is the code of the loop if it helps:
# Create labels and buttons in loop
y = 50
a = 0
for i in res:
# creates section name label
text = str(res[a][0])
text = text[19:]
text = text[:-1]
labelSectionName = Label(Text = text)
labelSectionName.Parent = self
labelSectionName.Location = Point(gridColSecName,y)
labelSectionName.Width = gridWidthSecName
#labelSectionName.Height = 20
# creates sheet number label
text = str(res[a][2])
labelSectionName = Label(Text = text)
labelSectionName.Parent = self
labelSectionName.Location = Point(gridColSheetNum,y)
labelSectionName.Width = 50
# create button for opening sheet
button = Button()
button.Parent = self
button.Text = "Open Sheet"
button.Location = Point(gridColButtSheet,y)
# Register button event
button.Click += self.?????????????????????????????????????
and this is the code for opening the sheet taken from another script
sheet = UnwrapElement(IN[0])
sheet_action=(IN[1])
output = []
if (str(sheet_action) == "Yes"):
uidoc.RequestViewChange(sheet)
output.append("ActiveView set to: " + sheet.Name)
else:
pass
OUT = sheet_action

Related

How to get the Values from the Entry box in Tkinter?

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

How to get every item inside a listbox in tkinter?

How do I make it so that I get all the items inside a listbox into a variable? I only manage to get the last item only. I want to print the items of a listbox into a new window but I only print the last item only.
get_content = listbox2.get(0, END)
bb = Label(receipt_window, text = "Pizzeria")
line1 = Label(receipt_window, text = "----------------------------------------------------------------")
for con_item in get_content:
con = (con_item.split('PHP'))
con1 = con[0]
con2 = con[1]
rec_content = f'{con1:<40}costs PHP{con2:<8}'
receipt = Label(receipt_window, text = rec_content)
bb.pack()
line1.pack()
receipt.pack()
The listbox contains:
The result:
It is because you use same variable receipt for the labels created inside the for loop and call receipt.pack() outside the for loop, so the last label created inside for loop will be packed only.
You need to call receipt.pack() inside the for loop:
get_content = listbox2.get(0, END)
bb = Label(receipt_window, text='Pizzeria')
line1 = Label(receipt_window, text='----------------------------------------------------------------')
bb.pack()
line1.pack()
for con_item in get_content:
con1, con2 = con_item.split('PHP')
rec_content = f'{con1:<40}costs PHP{con2:<8}'
receipt = Label(receipt_window, text=rec_content)
receipt.pack()
Note that it is better to use fixed width (monospaced) font for the labels.

Can't access elements in the same webpage after clicking with Python Selenium

I am trying to obtain the addresses of Walmart stores after searching Walmart.com by zip code using Python Selenium. I have searched here and online but I can't find a solution. The list of stores within the zip code populates, and I can loop through that list to get the name of each store, but then another click on a "Details" button is required to see the full address. After clicking on "Details" the information appears in the same area as the list of stores, but, I cannot obtain any information within the new "window" that appears after clicking "Details" and the looping stops. See pictures of the website below.
I have tried "wait.until(EC.visibility_of_element_located((By.XPATH..." and tried to switch between elements, windows and frames, but none of them work.
Here is some code I tried and you can see other things I tried that are commented out. While there are no errors, it doesn't work:
zip_code = '60639'
w_browser = webdriver.Chrome(ChromeDriverManager().install())
ws_url = 'https://www.walmart.com/store/finder?location=' + zip_code + '&distance=30'
w_browser.get(ws_url)
w_div = w_browser.find_elements_by_xpath('//*[#id="store-list"]/div/ol/li//a')
w_tic = str(0)
w_store_names = []
w_add_names = [] #
for ws in w_div:
w_tic = int(w_tic)
w_tic = w_tic +1
w_tic = str(w_tic)
try:
w_store = w_browser.find_element_by_xpath('//*[#id="store-list"]/div/ol/li[' + w_tic + ']/div/div[2]/span[1]/div[1]')
print(w_tic)
w_store_names.append(w_store.text)
print(w_store.text)
# main_page = w_browser.current_window_handle
# time.sleep(1)
# button = w_browser.find_element_by_link_text('store-icon-link-text')
button = w_browser.find_element_by_xpath('//*[#id="store-list"]/div/ol/li[' + w_tic + ']/div/div[2]/span[2]/span/span')
button.click()
time.sleep(1)
print('I clicked Details')
wait = WebDriverWait(w_browser, 5)
add_menu = wait.until(EC.visibility_of_element_located((By.XPATH,'//*[#id="store-finder-results"]/div/div/div[2]/div[3]/div/div[2]/div/div[1]/div')))
ActionChains(w_browser).move_to_element(add_menu).perform()
# back_button = w_browser.find_element_by_xpath('//*[#id="store-finder-results"]/div/div/div[1]/button/span/span[1]')
# back_button.click()
# store_button = find_element_by_xpath('//*[#id="store-finder-results"]/div/div/div[1]/a/button/span')
# action = ActionChains(w_browser)
# action.click(on_element = store_button)
# action.perform()
# for handle in w_browser.window_handles:
# if handle != main_page:
# add_page = handle
# w_browser.switch_to.window(add_page)
# w_frame = w_browser.find_element_by_xpath('//*[#id="store-finder-search-container"]')
# w_browser.switch_to.frame(w_frame)
w_ea = []
w_range = (1, 5)
for w_er in w_range:
w_elem = w_browser.find_element_by_xpath('//*[#id="store-finder-results"]/div/div/div[2]/div[3]/div/div[2]/div/div[1]/div/div[2]/span[' + str(w_er) + ']')
w_ea.append(w_elem.text)
print(w_elem)
w_add_names.append(w_ea)
# w_browser.switch_to.window(main_page)
# time.sleep(1)
except NoSuchElementException:
pass
print('WALMART STORES:')
print(w_store_names)
w_count = len(w_store_names)
print('There are ' + str(w_count) + ' Walmart Stores in Zip Code ' + str(zip_code))
w_browser.quit()
print(w_add_names)
I think that I have to somehow switch to the new (nested?) information pane that shows up after clicking "Details," and the switching back to get to the next store, but I don't know how. Any help would be much appreciated.

How can I create a table in a DOCX file with Python?

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

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.

Categories