How to hand over a dataframe between tkinter buttons? - python-3.x

I'm pretty new with python programming and this is my first question asked, so be gentle with me. Right now i am working on a tkinter GUI that reads CSV files, turns them into dataframes to edit them and save the processed file to a result.csv in a datapath. My Problem is that i want to read in the CSV with a function OpenFile() connected to one button and then use the returned dataframe in my "Editfunctions" that each also is connected to a button. That doesnt seem to work with my callback in the code. Here is what my tkinter GUI currently Looks like:
root = tk.Tk()
openbutton = tk.Button (root, text='OpenFile', command = lambda: OpenFile())
openbutton.pack()
brakebutton = tk.Button (root, text = 'EditFile', command = lambda: EditFile(z))
brakebutton.pack()
savenewbutton = tk.Button(root, text = 'SavetoNewFile', command = lambda: SaveinNewFile(out_tup_end3))
savenewbutton.pack()
saveexcbutton = tk.Button(root, text = 'AppendtoExistingFile', command = lambda: SavetoexistingFile(out_tup_end3))
saveexcbutton.pack()
root.mainloop()
MY functions essentially look like this:
def OpenFile():
name = askopenfilename()
df = pd.read_csv(name, sep = ';')
return df
def EditFile(z):
df1 = z[[]]
.
.
.
.
return out_tup_end3
def SaveinNewFile(out_tup_end3):
out_tup_end3.to_csv("datapath", sep = ';', index = 0, mode = 'w')
def SavetoexistingFile(out_tup_end3):
with open("datapath", 'a') as f:
out_tup_end3.to_csv(f, header=False, sep = ';', index = 0)
def main():
z = OpenFile()
EditFile(z)
editedFile = EditFile(z)
SaveinNewFile(editedFile)
SavetoexistingFile(editedFile)
if __name__ == "__main__":
main()
So I think the not properly working part is that the callback is not handing over the dataFrame read from OpenFile() to EditFile(z). How can i achieve that?
Thanks for the help in advance!!

command= executes function but it doesn't care of value returned from this function so you have to use global variables to use result from one function in other function.
You code could look like this
#!/usr/bin/env python3
import tkinter as tk
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import showinfo, showwarning
import pandas as pd
# --- functions ---
def open_file():
# inform function to use global variables
global df
name = askopenfilename()
if name:
df = pd.read_csv(name, sep=';')
showinfo("INFO", "DataFrame created")
def edit_file():
# inform function to use global variables
global df, out_tup_end3
if df is None:
#print("Read file first")
showwarning("WARNING", "Read file first")
else:
df1 = df[[]]
# ...
out_tup_end3 = df1
showinfo("INFO", "DataFrame edited")
def save_in_new_file():
# inform function to use global variables
global out_tup_end3
if out_tup_end3 is None:
#print("Read file first")
showwarning("WARNING", "Read file first")
else:
out_tup_end3.to_csv("datapath", sep=';', index=0, mode='w')
showinfo("INFO", "DataFrame saved")
def save_to_existing_file():
# inform function to use global variables
global out_tup_end3
if out_tup_end3 is None:
#print("Read file first")
showwarning("WARNING", "Read file first")
else:
with open("datapath", 'a') as f:
out_tup_end3.to_csv(f, header=False, sep=';', index=0)
showinfo("INFO", "DataFrame appended")
# --- main ---
if __name__ == "__main__":
# create global variables
df = None
out_tup_end3 = None
# GUI
root = tk.Tk()
b = tk.Button(root, text='Open File', command=open_file)
b.pack(fill='x')
b = tk.Button(root, text='Edit File', command=edit_file)
b.pack(fill='x')
b = tk.Button(root, text='Save to New File', command=save_in_new_file)
b.pack(fill='x')
b = tk.Button(root, text='Append to Existing File', command=save_to_existing_file)
b.pack(fill='x')
root.mainloop()
Or learn how to use classes and self. instead of global

Related

Display messages in window tkinter

I am working on the following small tkinter application.
The URL & token is for a public development demo which can be found here if interested - https://snipe-it.readme.io/reference#api-overview
My current issue is displaying logging messages to the current tkinter window.
Currently it just prints to the console. I've tried a few different methods but I'm not very good with tkinter at the moment.
I have tried solutions like so - How do I create a popup window in tkinter? - but this just duplicates the main window each time.
Any help or pointers would be appreciated.
The csv file looks like so:
asset_tag,
1382613192,
1169063140,
785100692,
4565667567345457574535,
import csv
import logging
from datetime import datetime
from multiprocessing import Process, Queue
from tkinter import *
from tkinter import filedialog, ttk
from tkinter.messagebox import showinfo
import requests
#todo set initialdir as current user
# initiate logging module
logging.basicConfig(level=logging.INFO)
# set headers are they are used in several functions
headers = {
"Accept": "application/json",
"Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImVmMGVhY2Y4MjAyYzgwZWI2M2JkNmIwZDc0OGYwY2FkYzU2Y2ZlMzgyNzY4ODY0N2EwNmU4ZTBlNmYwZDgwODNjZmMyMzI2YWYyYTZlMTFkIn0.eyJhdWQiOiIxIiwianRpIjoiZWYwZWFjZjgyMDJjODBlYjYzYmQ2YjBkNzQ4ZjBjYWRjNTZjZmUzODI3Njg4NjQ3YTA2ZThlMGU2ZjBkODA4M2NmYzIzMjZhZjJhNmUxMWQiLCJpYXQiOjE0OTMzMzI2MjgsIm5iZiI6MTQ5MzMzMjYyOCwiZXhwIjoxODA4ODY1NDI4LCJzdWIiOiIyIiwic2NvcGVzIjpbXX0.NU7ZRIt-d4b0o8uv9ipo1vSWcg1svbmPp47kHErafm9iuK4FjygKd2_4Hp73HKAmjiYcEn3r39pwNh2t9BMFnTXv0KeDGC8zfZ9z7OJN_a59LPoarWBFzCsYETyAm-CeeFnfdj9Cr0ZeGOnnaPuWPYxicwKFeqJI4Hn8nCymcamDGE0u4WOO95ihGOAen4_fqpj-kkBDsvsGhB-cQxeuKdlbvO1yOsKmgQv-kQuxiFMn1zgU7P02mC6XXrbw6jTm7JOaBSbvqSwNtsrSKZkim1jxLsQ4dm36lFmeMkU6hZvNSUnxg8JwbmoxQ_3tZlG3IJh3Sc9ZUi-AEAQ4bbGzi_xNS9fenIdzLDaSiv_esYyNOYXqOuSBk8Yr-720N9OcVjGLnPrV3RtmPisV1aLFgKWLImtlyQgUq3d5LA3QXz8Q_8isvO9Am1u8ri2plbHGJLJ6GRW_mYcBEYMwUozaeXTUe_FUSSO8gpGtO9Hpa5SbERY272_tojyVXpYPaPdUYYmS9CP332jBNESPT8wGwpOM-iddeVo_n82w3dHmDEdp1Brbs3_vKk0AcgvDLsAbd4dZZO-UqddVx6SDb3HLw1Pmw1wGGYHA6w8wWQAiS9kg2xMcz5i75HOULaN3miqYvcPCvHpI2CBfuvdplI8QNm_XzFPmoQRu_5kR8knzla4",
"Content-Type": "application/json"
}
# functions
def check_in(id, asset_tag, headers):
# check in function, takes the asset ID and POST's to the url
# can optionally set a checkin note in the payload
url = "https://develop.snipeitapp.com/api/v1/hardware/"+id+"/checkin"
# modify if you would like a note with the checkin
payload = {"note": "checked in by ME"}
try:
response = requests.request("POST", url, json=payload, headers=headers)
checkin_response = response.json()
'''
This if statement is required here because if the asset is already checked in, it still returns an http successful message.
So this checks if the value in the status key is equal to "error" and if so then it will log this as an error.
'''
if "error" in checkin_response['status']:
logging.error("Unable to checkin asset %s - %s"
% (asset_tag, checkin_response['messages']))
else:
logging.info("Successfully checked in asset %s" % (asset_tag))
# catch any http errors and continue
except requests.exceptions.RequestException as e:
logging.error(e)
pass
def get_asset_id(asset_tag, output_q, headers):
# this function gets the asset id from a given asset tag
url = "https://develop.snipeitapp.com/api/v1/hardware/bytag/"+asset_tag+""
output_dict = {}
try:
response = requests.request("GET", url, headers=headers, verify=False)
response.raise_for_status()
json_response = response.json()
'''
This checks if the status key exists in the response and if it does then it returns an error.
This is because the status key does not exist at all in a successful query.
Again this is required because even if the asset tag doesn't exist, it still returns http 200.
'''
if "status" in json_response:
logging.error("Unable to retrieve asset ID for asset tag %s - %s"
% (asset_tag, json_response['messages']))
else:
logging.info("Successfully retrieved asset ID from %s" %
(asset_tag))
asset_id = str(json_response['id'])
check_in(asset_id, asset_tag, headers)
except requests.exceptions.RequestException as e:
logging.error(e)
pass
output_q.put(output_dict)
# class for tkinter configuration
class App:
def __init__(self, master):
self.label = ttk.Label(master, text="Bulk Checkin")
self.label.grid(row=0, column=0, columnspan=2)
ttk.Button(master, text="Select File",
command=self.select_file).grid(row=2, column=0)
ttk.Button(master, text="Checkin Assets",
command=self.checkin_assets).grid(row=2, column=1)
def select_file(self):
filename = filedialog.askopenfilename(initialdir="C:/Users/fraser/Desktop/", filetypes=(("CSV Files","*.csv"),))
self.infile = open(filename, "r")
print(self.infile.name)
def checkin_assets(self):
# function for Checkin Assets button click
# start a timer so we can see how long it takes
start_time = datetime.now()
output_q = Queue(maxsize=20)
procs = []
with open(self.infile.name, 'r') as myfile:
csv_reader = csv.DictReader(myfile)
line_count = 0
for row in csv_reader:
if line_count == 0:
", ".join(row)
line_count += 1
line_count += 1
asset_tag = row["asset_tag"]
my_proc = Process(target=get_asset_id, args=(
asset_tag, output_q, headers))
my_proc.start()
procs.append(my_proc)
# Make sure all processes have finished
for a_proc in procs:
a_proc.join()
# log how long this took
logging.info("\nElapsed time: " + str(datetime.now() - start_time))
def main():
main = Tk()
app = App(main)
main.mainloop()
if __name__ == "__main__":
main()
Here you go, this is assuming you want the messages as a popup. If not, create your own messaging window, or add a label or something you can update to the main one. I used the two messaging classes from the referenced post, but you can call them from anywhere and pass a message you want displayed.
import csv
import logging
from datetime import datetime
from multiprocessing import Process, Queue
from tkinter import *
from tkinter import filedialog, ttk
from tkinter.messagebox import showinfo
class App(ttk.Frame):
def __init__(self, master):
ttk.Frame.__init__(self, master)
self.label = ttk.Label(master, text="Bulk Checkin")
self.label.grid(row=0, column=0, columnspan=2)
ttk.Button(master, text="Select File",
command=self.select_file).grid(row=2, column=0)
ttk.Button(master, text="Checkin Assets",
command=self.checkin_assets).grid(row=2, column=1)
def select_file(self):
filename = filedialog.askopenfilename(initialdir="C:/Users/fraser/Desktop/", filetypes=(("CSV Files","*.csv"),))
self.infile = open(filename, "r")
print(self.infile.name)
def checkin_assets(self):
# function for Checkin Assets button click
# start a timer so we can see how long it takes
start_time = datetime.now()
output_q = Queue(maxsize=20)
procs = []
with open(self.infile.name, 'r') as myfile:
csv_reader = csv.DictReader(myfile)
line_count = 0
for row in csv_reader:
if line_count == 0:
", ".join(row)
line_count += 1
line_count += 1
asset_tag = row["asset_tag"]
my_proc = Process(target=get_asset_id, args=(
asset_tag, output_q, headers))
my_proc.start()
procs.append(my_proc)
# Make sure all processes have finished
for a_proc in procs:
a_proc.join()
# log how long this took
logging.info("\nElapsed time: " + str(datetime.now() - start_time))
def popup_bonus(self, message):
win = Toplevel()
win.wm_title("Message")
l = Label(win, text=message)
l.grid(row=0, column=0)
b = ttk.Button(win, text="Ok", command=win.destroy)
b.grid(row=1, column=0)
def popup_showinfo(self, message):
showinfo("Message", message)
def main():
main = Tk()
app = App(main)
main.mainloop()
if __name__ == "__main__":
main()
I use easygui because it is the simplest and one-liner. It can work alongside tkinter so there is no compatibility issues. For example, if you want a messagebox/alert, just do this:
import easygui
easygui.msgbox('in cmd, type: "shutdown -a" within 20 seconds', title="Chance to abort shutdown")

How do I pass dynamic parameters as arguments

I have the following code :
from tkinter import *
class GUI:
def __init__(self,master):
self.ip_word = Label(master,text="Input Path")
self.ip_word.grid(row=0,sticky=E)
self.ip_path_field = Entry(master)
self.ip_path_field.grid(row=0,column=1,sticky=W)
self.op_word = Label(master,text="Output Path")
self.op_word.grid(row=2,sticky=E)
self.op_path_field = Entry(master)
self.op_path_field.grid(row=2,column=1,sticky=W)
self.filename_word=Label(master,text="Output Filename ")
self.filename_word.grid(row=4,sticky=E)
self.filename =Entry(master)
self.filename.grid(row=4,column=1,sticky=W)
self.Submit = Button(master,text="Submit",fg="black",bg="white",command=self.Scraper(ip_path_field,op_path_field,filename) )
self.Submit.grid(row=5,columnspan=2)
"""
def printMessage(self):
str1=ip_path_field
str2=op_path_field
str3=filename
Scraper(str1,str2,str3)"""
def Scraper(self,ip_path_field,op_path_field,filename):
import pandas as pd
import os
# "C:/Users/chowdhuryr/Desktop/first automation/MAIN RESEARCH DATA.xlsx"
user_input =ip_path_field#input("Enter the input file path of your file: ")
if os.path.exists(user_input):
df = pd.read_excel(user_input, sheetname='Sheet1')
print("File Found and We are Processing !")
else:
print ("Input Directory does not exists.")
#"C:/Users/chowdhuryr/Desktop/first automation/OUTPUT DATA.xlsx"
user_output =op_path_field#input("Enter the output file path of your file: ")
#if os.path.exists(user_input):
#df = pd.read_excel(user_input, sheetname='Sheet1')
#--------------------------------------------------------------------------------------------------------------------------------------
#setting up the path
import os
os.chdir('C:/Users/chowdhuryr/Desktop/first automation')
df=df[0:5]
#--------------------------------------------------------------------------------------------------------------------------------------
#importing necessary packages
from selenium import webdriver
#from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException
#---------------------------------------------------------------------------------------------------------------------------------------
#Setting up Chrome webdriver
#chrome_options = webdriver.ChromeOptions()
options = webdriver.ChromeOptions()
options.add_argument("--headless") #making the window work in the background
options.add_argument('window-size=1200x850')
#declaring a list to store the messages
Message=list()
Tier=list()
Wirecentre=list()
#---------------------------------------------------------------------------------------------------------------------------------------
#iteration to access the url and and retriving the Tier Locations
for i in range(0,df.shape[0]): #(0,df.shape[0]):
driver = webdriver.Chrome(executable_path='C:/Users/chowdhuryr/Desktop/first automation/chromedriver', chrome_options=options) #openning chrome
#driver.maximize_window() #maximizing the window
driver.get('https://clec.att.com/facilitiescheck/facilities_chk.cfm') #openning the url
street_address=driver.find_element_by_xpath('/html/body/form/table/tbody/tr[2]/td[2]/table/tbody/tr[1]/td[2]/input') #accessing the street address field
street_address.send_keys(df['CIRCUIT_LOC_ADDR'][i].split(',')[0]) #passing the values to street_address location
city=driver.find_element_by_xpath('/html/body/form/table[1]/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/input') #accessing the city to street address field
city.send_keys(df['CIRCUIT_LOC_ADDR'][i].split(',')[1]) #passing the values to the city location
state=driver.find_element_by_xpath('/html/body/form/table[1]/tbody/tr[2]/td[2]/table/tbody/tr[4]/td[2]/select') #accessing the state field
state.send_keys(df['CIRCUIT_LOC_ADDR'][i].split(',')[2]) #passing the values to the state field
checkbox=driver.find_element_by_xpath('/html/body/form/table[1]/tbody/tr[2]/td[2]/table/tbody/tr[8]/td[1]/input') #accessing the checkbox
checkbox.click() #clicking on the check box
search_button=driver.find_element_by_xpath('/html/body/form/table[1]/tbody/tr[2]/td[2]/table/tbody/tr[8]/td[1]/input') #accessing the submit button
search_button.submit() #clicking the submit button
#try-except block in case if radio button appears
try:
Address=driver.find_element_by_xpath('/html/body/form/table[2]/tbody/tr[1]/td[2]/b') #taking the xpath of the address block
if (Address): #checking if it contains any radio button or not
Radio_button=driver.find_element_by_xpath('/html/body/form/table[2]/tbody/tr[2]/td[1]/input') #getting the xpath of radio button
Radio_button.click() #clicking the radio button
submit_button=driver.find_element_by_xpath('/html/body/form/table[3]/tbody/tr[2]/td/input') #getting the submit button
submit_button.submit()
except NoSuchElementException:
print('no such element found')
message_body= driver.find_element_by_xpath('//*[#id="msg"]/table/tbody/tr/td').text #Extracting the Message from the message box
Message.append(message_body[14:]) #putting the message into a text
str = message_body.split() #splitting the message
if any ("Tier"in s for s in str):
j=str.index('Tier')
Tier.append(str[j+1])
else:
Tier.append("NULL")
if any ("AT&T"in s for s in str):
j=str.index('AT&T')
Wirecentre.append(str[j+1])
else:
Wirecentre.append("NULL")
#saving the screenshot
str=df['STRIP_EC_CIRCUIT_ID'][i]
filename="C:\\Users\\chowdhuryr\\Desktop\\first automation\\"+str+".png" #Taking the circuit id name
driver.get_screenshot_as_file(filename)
driver.close() #closiing the driver
#------------------------------------------------------------------------------------------------------------------------------------------
#putting the back thenew columns into the dataframe and storing it into an excel sheet
df['Tier']=Tier #putting the Tier column back into the dataset
df['Wirecentre']=Wirecentre #putting the Wirecentre column back into the dataset
df['Message']=Message #putting the Message column back into the dataset
if os.path.exists(user_output):
user_output="user_output"+filename+".xlsx"
writer = pd.ExcelWriter(user_output) #writing the dataframe down into a new excel file
df.to_excel(writer,'sheet1',index=False) #to_excel(writer,'Sheet1')
writer.save()
else:
print ("Output Directory does not exists.")
#-------------------------------------------------------------------------------------------------------------------------------------------
#Generating pop up window at the end of the process
popup_driver=webdriver.Chrome()
popup_driver.maximize_window()
popup_driver.execute_script(" window.alert('Process is Completed');") #generating the pop up """
root =Tk()
b=GUI(root)
#b.Scraper(ip_path_field,op_path_field,filename)
root.mainloop()
Now what I want to do is this :
I want to pass the variables ip_path_field,op_path_field,filename as arguments to the function named scraper . Now ip_path_field,op_path_field,filename are all user inputs and not hard coded strings. Now whenever I run the following code, I get the GUI opened and whenever I provide my inputs in the required edit boxes and press the submit button I get the following error name 'ip_path_field' is not defined. My purpose of this code is to pass the user defined file paths to the function called scraper() as defined in the code above.
You need to create a callback that gets the values, and then passes them to the function that does the work.
Example:
class GUI:
def __init__(self,master):
...
self.Submit = Button(..., command=self.handle_submit)
...
def handle_submit(self):
ip_path = self.ip_path_field.get()
op_path = self.op_path_field.get()
filename = self.filename.get()
self.Scrapper(ip_path_field,op_path_field,filename)
The main problem you are having is related to how you built your method. Instead you should have put the get() calls inside that method. This way you can simple run the command to call scraper without needing to pass arguments. I have taken your code and re-written it to more closely follow the PEP8 standard with the method correction included.
You only need to apply the self. prefix to class attributes/methods. Things like labels/buttons that are not going to be modified later in the code should be left as normal widgets that are not assigned as attributes.
Next I moved all your imports to the top of the code. You only need to import a library one time and it should all be listed at the top of your code. On imports keep in mind it is better to import tkinter as tk instead of using * to prevent any accidental overrides occurring.
I have changed your string concatenation to use the format() method as + is deprecated.
Here is your code with some basic clean up as well.
import tkinter as tk
import pandas as pd
import os
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
class GUI:
def __init__(self,master):
tk.Label(master, text="Input Path").grid(row=0, sticky="e")
tk.Label(master, text="Output Path").grid(row=2, sticky="e")
tk.Label(master, text="Output Filename").grid(row=4, sticky="e")
self.ip_path_field = tk.Entry(master)
self.op_path_field = tk.Entry(master)
self.filename = tk.Entry(master)
self.ip_path_field.grid(row=0, column=1, sticky="w")
self.op_path_field.grid(row=2, column=1, sticky="w")
self.filename.grid(row=4, column=1, sticky="w")
tk.Button(master, text="Submit", fg="black", bg="white",
command=self.scrapper).grid(row=5,columnspan=2)
def scrapper(self): # changed function to a method.
user_input = self.ip_path_field.get(0, "end")
user_output = self.op_path_field.get(0, "end")
filename = self.filename.get(0, "end")
if os.path.exists(user_input):
df = pd.read_excel(user_input, sheetname='Sheet1')
print("File Found and We are Processing !")
else:
print ("Input Directory does not exists.")
os.chdir('C:/Users/chowdhuryr/Desktop/first automation')
df = df[0:5]
options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument('window-size=1200x850')
message = list()
tier = list()
wirecentre = list()
for i in range(0,df.shape[0]):
driver = webdriver.Chrome(executable_path='C:/Users/chowdhuryr/Desktop/first automation/chromedriver', chrome_options=options)
driver.get('https://clec.att.com/facilitiescheck/facilities_chk.cfm')
street_address = driver.find_element_by_xpath('/html/body/form/table/tbody/tr[2]/td[2]/table/tbody/tr[1]/td[2]/input')
street_address.send_keys(df['CIRCUIT_LOC_ADDR'][i].split(',')[0])
city=driver.find_element_by_xpath('/html/body/form/table[1]/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/input')
city.send_keys(df['CIRCUIT_LOC_ADDR'][i].split(',')[1])
state = driver.find_element_by_xpath('/html/body/form/table[1]/tbody/tr[2]/td[2]/table/tbody/tr[4]/td[2]/select')
state.send_keys(df['CIRCUIT_LOC_ADDR'][i].split(',')[2])
checkbox = driver.find_element_by_xpath('/html/body/form/table[1]/tbody/tr[2]/td[2]/table/tbody/tr[8]/td[1]/input')
checkbox.click()
search_button = driver.find_element_by_xpath('/html/body/form/table[1]/tbody/tr[2]/td[2]/table/tbody/tr[8]/td[1]/input')
search_button.submit()
try:
address = driver.find_element_by_xpath('/html/body/form/table[2]/tbody/tr[1]/td[2]/b')
if (address):
radio_button = driver.find_element_by_xpath('/html/body/form/table[2]/tbody/tr[2]/td[1]/input')
radio_button.click()
submit_button = driver.find_element_by_xpath('/html/body/form/table[3]/tbody/tr[2]/td/input')
submit_button.submit()
except NoSuchElementException:
print('no such element found')
message_body = driver.find_element_by_xpath('//*[#id="msg"]/table/tbody/tr/td').text
message.append(message_body[14:])
strx = message_body.split()
if any ("Tier"in s for s in strx):
j = strx.index('Tier')
tier.append(strx[j+1])
else:
tier.append("NULL")
if any ("AT&T"in s for s in strx):
j = strx.index('AT&T')
wirecentre.append(strx[j+1])
else:
wirecentre.append("NULL")
strx = df['STRIP_EC_CIRCUIT_ID'][i]
filename = "C:\\Users\\chowdhuryr\\Desktop\\first automation\\{}.png".format(strx)
driver.get_screenshot_as_file(filename)
driver.close()
df['Tier'] = tier
df['Wirecentre'] = wirecentre
df['Message'] = message
if os.path.exists(user_output):
user_output="user_output{}.xlsx".format(filename)
writer = pd.ExcelWriter(user_output)
df.to_excel(writer, 'sheet1', index=False)
writer.save()
else:
print ("Output Directory does not exists.")
popup_driver = webdriver.Chrome()
popup_driver.maximize_window()
popup_driver.execute_script(" window.alert('Process is Completed');")
root = tk.Tk()
b = GUI(root)
root.mainloop()
All that said you should try to use a minimal code next time. It is easier to fix issues when you narrow it down to exactly the problem. For example based on your question a Minimal, Complete, and Verifiable example would look something like this.
from tkinter import *
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
class GUI:
def __init__(self,master):
self.ip_path_field = Entry(master)
self.ip_path_field.grid(row=0,column=1,sticky=W)
self.op_path_field = Entry(master)
self.op_path_field.grid(row=2,column=1,sticky=W)
self.filename =Entry(master)
self.filename.grid(row=4,column=1,sticky=W)
self.Submit = Button(master, text="Submit",
command=self.Scrapper(ip_path_field,op_path_field,filename) )
self.Submit.grid(row=5,columnspan=2)
def Scrapper(self,ip_path_field,op_path_field,filename):
user_input = ip_path_field
user_output = op_path_field
filename = filename
root = Tk()
b = GUI(root)
root.mainloop()

Bug appears when writing file from tkinter module

import tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.pack()
self.create_widgets()
def create_widgets(self):
self.hi_there = tk.Button(self)
self.hi_there["text"] = "Done!\n(click me)"
self.hi_there["command"] = self.say_hi
self.hi_there.pack(side="top")
self.entrythingy = tk.Entry()
self.entrythingy2 = tk.Entry()
self.entrythingy.pack()
self.entrythingy2.pack()
# here is the application variable
self.contents = tk.StringVar()
self.contents2 = tk.StringVar()
# set it to some value
self.contents.set("stdio")
self.contents2.set("script name")
# tell the entry widget to watch this variable
self.entrythingy["textvariable"] = self.contents
self.entrythingy2["textvariable"] = self.contents2
self.text = tk.Text()
self.text.pack()
# and here we get a callback when the user hits return.
# we will have the program print out the value of the
# application variable when the user hits return
self.entrythingy.bind('<Key-Return>',
self.print_contents)
self.quit = tk.Button(self, text="QUIT", fg="red",
command=root.destroy)
self.quit.pack(side="bottom")
def say_hi(self):
#print("hi there, everyone!")
self.fn = self.contents2.get()
self.body = self.text.get(1.0, tk.END).split('\n')
#print('Self.body:\n',self.body)
self.libs = self.contents.get().split(' ')
self.make_c()
def make_c(self):
lib_text = ''
for i in self.libs:
lib_text += "#include <lib.h>\n".replace('lib', i)
body_text = "int main() {\n\t"+"\n\t".join(self.body)+"return 0\n}"
print(lib_text+body_text)
with open(self.fn+'.c', 'w+') as f:
f.write(lib_text+body_text)
print('File written!')
from subprocess import call
call(['gcc',self.fn+'.c', '-o', self.fn])
def print_contents(self, event):
print("hi. contents of entry is now ---->",
self.contents.get())
#self.contents.set("")
#def
root = tk.Tk()
app = Application(master=root)
app.mainloop()
Those are the my code, which tries to make a c file and convert it. The problem is, when I convert it once, it is working fine, but when I change the content of the text box, the file doesn't change, and I don't understand why. I am sure that I put in the new file content, because it prints before it writes. Also, it appears that when I try to write files independent from tkinter, it works just the way I want it to.
I think there is some mechanism that I am not aware of in TK, or there is a bug. Please help me out, thanks.
I solved it. It doesn't compile again due to the error in it when I added return 0, without semicolon. So, when I click the executable file, it shows the old program. I added the semicolon, and now it is fine. Thx everyone!

Stop a working function with a button (Python, Tkinter)

I have a little situation with Tkinter. I have a piece of code that constantly receives raw EMG data from Thalmic`s Myo Armband and writes that data (plus the name of a gesture) to a csv file. I designed a little tkinter interface to make it look more user-friendly. What I need is to write a function that will stop the previously started recording function.
Also I have a problem with the label, that shows the number of rows in a csv file, but it is another question.
Here is the code:
from gesture_classificator import MyoRaw
import csv
import tkinter
import tkinter.messagebox
import sys
root = tkinter.Tk()
root.title("Recording data")
m = MyoRaw(sys.argv[1] if len(sys.argv) >= 2 else None)
v = tkinter.StringVar()
entry = tkinter.Entry(root, textvariable=v)
entry.grid(row=0, column=0)
v.set("")
def process_emg(emg, times):
name = v.get()
with open('own_test.csv', 'a+') as file:
writing = csv.writer(file)
writing.writerow(emg+(name,))
def show_row_count():
with open('own_test.csv', 'r') as return_me_the_row_count:
reading = csv.reader(return_me_the_row_count)
data = list(reading)
row_count = len(data)
return row_count
def start_recording():
m.add_emg_handler(process_emg)
m.connect()
def stop_recording():
???
B1 = tkinter.Button(root, text="Start the recording", command=start_recording)
B2 = tkinter.Button(root, text="Stop the recording", command=stop_recording)
rows_number = tkinter.Label(root, text=show_row_count)
rows_number.config(text=show_row_count)
B1.grid(row=1, column=0)
B2.grid(row=1, column=1)
rows_number.grid(row=0, column=1)
root.mainloop()
try:
while True:
m.run(1)
except SystemExit:
pass
finally:
m.disconnect()
According to the MyoRaw code, you would probably like the function MyoRaw.disconnect(), which you would use like this:
def stop_recording():
m.disconnect()
In such cases it would be easier and faster for you to check the documentation and/or the code of the framework you are using.

How can I save output tho the same file that I have got the data from, in Python 3

I am trying to open a file, remove some characters (defined in dic) and then save it to the same the file.
I can print the output and it looks fine, but I cannot save it into the same file that the original text is being loaded from.
from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import showerror
import sys
import fileinput
dic = {'/':' ', '{3}':''};
def replace_all(text, dic):
for i, j in dic.items():
text = text.replace(i, j)
return text
class MyFrame(Frame):
def __init__(self):
Frame.__init__(self)
self.master.title("Example")
self.master.rowconfigure(5, weight=1)
self.master.columnconfigure(5, weight=1)
self.grid(sticky=W+E+N+S)
self.button = Button(self, text="Browse", command=self.load_file, width=10)
self.button.grid(row=1, column=0, sticky=W)
def load_file(self):
fname = askopenfilename(filetypes=(("Napisy", "*.txt"),
("All files", "*.*") ))
if fname:
try:
with open (fname, 'r+') as myfile: #here
data = myfile.read() #here
data2 = replace_all(data, dic) #here
print(data2) #here
data.write(data2) #and here should it happen
except:
showerror("Open Source File", "Failed to read file\n'%s'" % fname)
return
if __name__ == "__main__":
MyFrame().mainloop()
I have tried several commands but either I am receiving python errors or it is simply not working.
This is often implemented by writing to a temp file and then moving it to the original file's name.
Strings do not have a .write method. The following should work (I tried it): replace
data.write(data2) #and here should it happen
with
myfile.seek(0)
myfile.truncate()
myfile.write(data2)
The truncate() call is needed if data2 is shorter than data as otherwise, the tail end of data will be left in the file.

Resources