How to apply selecting a file button in python - python

I learned how to create a select file button but I don't know how to apply it to the code as you can see below.
from openpyxl import Workbook
# import copy
wb = Workbook()
with open('chat_20220222152420.txt', encoding='utf-8') as sherr:
row = 1
column = 1
ws = wb.active
for line in sherr:
if column == 1:
## split the line and rejoin
value = " ".join(line.strip().split(' ')[2:])
else:
value = line.strip()
ws.cell(row=row, column=column, value=value)
if (column := column + 1) > 3:
row += 1
column = 1
wb.save('Chatchatchat.xlsx')
Instead of using the with open(), I wanted to use a button to choose the file I wanted to open. Below is the code I tried for selecting a file. I just don't know how to apply it in the above code :'(
from ipywidgets import Button
from tkinter import Tk, filedialog
from IPython.display import clear_output, display
def select_files(b):
root = Tk()
root.withdraw() # Hide the main window.
root.call('wm', 'attributes', '.', '-topmost', True) # Raise the root to the top of all windows.
b.files = filedialog.askopenfilename(multiple=False) # List of selected files will be set button's file attribute.
print(b.files) # Print the list of files selected.
fileselect = Button(description="File select")
fileselect.on_click(select_files)
display(fileselect)

One way to do this is to move the first block of code into a function that takes a filename to read:
from openpyxl import Workbook
def write_spreadsheet(filename):
wb = Workbook()
with open(filename, encoding='utf-8') as sherr:
row = 1
# ...
Then call it from select_files (note that filedialog.askopenfilename returns a single filename, not a list):
def select_files(b):
root = Tk()
root.withdraw() # Hide the main window.
root.call('wm', 'attributes', '.', '-topmost', True) # Raise the root to the top of all windows.
file = filedialog.askopenfilename(multiple=False) # Ask the user to select a file.
print(file) # Print the file selected.
write_spreadsheet(file) # Process the file.

Related

Word file keyword or text importing and save to excel sheet using python gui tkinter

I created a python gui using tkinter, the gui gui is showing but during i need to locate the Microsoft word files containing the .docx and .doc it can't see but empty folder. The importing and extraction will not proceed since it doesn't see the word files.
I install the modules,
as python script shown below. Any idea?
Analyze Python Program Requested
import docx
import openpyxl
import os
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import filedialog
import threading
import win32com.client
Set the default directory and output location
default_directory = '/path/to/default/directory'
output_location = None
Create the GUI
root = tk.Tk()
root.geometry("300x250")
root.title('Data Extractor')
Create a label to display the current directory
label = tk.Label(root, text='Directory: ' + default_directory)
label.pack()
Create a button to select the directory
def select_directory():
global default_directory
directory = filedialog.askdirectory()
if directory:
default_directory = directory
label.config(text='Directory: ' + default_directory)
button = tk.Button(root, text='Set Directory', command=select_directory)
button.pack()
Create a button to select the output location
def select_output_location():
global output_location
output_location = filedialog.asksaveasfilename(defaultextension='.xlsx', filetypes=[("Excel Workbook", "*.xlsx")])
if output_location:
output_label.config(text='Output: ' + output_location)
output_label = tk.Label(root, text='Output: ')
output_label.pack()
output_button = tk.Button(root, text='Set Output Location', command=select_output_location)
output_button.pack()
Create a progress bar
progress = ttk.Progressbar(root, length=200)
progress.pack()
Create a button to start the extraction
def extract_data():
if default_directory and output_location:
thread = threading.Thread(target=extract_data_thread)
thread.start()
else:
tk.messagebox.showerror("Error", "Please select the directory, output location and check if it contain word files")
def extract_data_thread():
# Create a new Excel workbook
workbook = openpyxl.Workbook()
# Create a new sheet
sheet = workbook.create_sheet()
# Set the starting row for the data
row = 1
# Set the directory to the default or selected directory
directory = default_directory
# Get the number of files to process
file_count = 0
for root, dirs, files in os.walk(directory):
file_count += len([f for f in files if f.endswith(('.docx', '.doc'))])
# Set the progress bar maximum value
progress['maximum'] = file_count
progress['value'] = 0
processed_files = 0
# Iterate over the files in the directory
for root, dirs, files in os.walk(directory):
for filename in files:
if filename.endswith(('.docx', '.doc')):
try:
if filename.endswith('.docx'):
doc = docx.Document(os.path.join(root, filename))
tables = doc.tables
elif filename.endswith('.doc'):
word = win32com.client.Dispatch("Word.Application")
doc = word.Documents.Open(os.path.join(root, filename))
tables = doc.Tables
else:
continue
if tables:
table = tables[0]
model_no = table.cell(0,1).text
reference_number = table.cell(0,2).text
date_released = table.cell(1,1).text
else:
continue
except:
print("An error occurred while processing file: " + filename)
continue
# Add the data to the sheet
sheet.cell(row=row, column=1).value = filename
sheet.cell(row=row, column=2).value = model_no
sheet.cell(row=row, column=3).value = reference_number
sheet.cell(row=row, column=4).value = date_released
# Increment the row counter
row += 1
# Update the progress bar
processed_files += 1
progress.set(processed_files)
root.update()
if processed_files == 0:
tk.messagebox.showerror("Error", "No word files or keyword detected")
else:
# Save the workbook
workbook.save(output_location)
progress['value'] = 0
print("Successfully saved data to: " + output_location)
Create the "Extract Data" button
extract_button = tk.Button(root, text='Extract Data', command=extract_data)
extract_button.pack()
root.mainloop()
any idea how solve the issue?

Python - tkinter askopenfilename function somehow stays active while selecting the file "directly" doesn't

I'm not a programmer so admittingly my title might be a bit off.
I have a program where I select an IFC-file (used in the construction industry, which contains data about the geometry and data connected to the objects in the 3D drawing) and then a dialog opens where I can add a GUID (an identifier) and search for all the information related to that object in the IFC-file, which I then print in the command prompt.
A minor issue which annoys me a bit is that the when is select the file in a more flexible way, using askopenfilename, the function seems to stay active or in a loop after I close the later opening dialog, so that I have to end the process using CTRL+C.
I post the entire code as I don't know if there is something else which causes it:
#imports to search for files
import os
# imports tkinter for selection purposes, so that one can select the files instead of reading in them automaticall from a directory
import tkinter as tk
from tkinter.filedialog import askopenfilename
#importing the counter to counte the occurences in a list
from collections import Counter
#importing regex functionality to check values
import re
#this is the numbering, for example #433, #4781 etc, that we either want to look for or change - now it looks for up to a number of length 7
regexIFCnumbers = '#\d{1,7}'
tk.Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
file1 = askopenfilename(initialdir=os.getcwd()) # show an "Open" dialog box and return the path to the selected file - this in the current directory where we'll start looking
file1Name = (os.path.basename(file1)) #only the file's name
#read files
def readFile(file):
x = []
f = open(file, 'r')
x = f.readlines()
f.close()
return(x)
x1 = readFile(file1)
#checks the GUIDs
def checkGUID(GUID, IFC):
A = []
for row in IFC:
if GUID in row:
#print(re.findall(regexIFCnumbers, row))
A.extend(re.findall(regexIFCnumbers, row))
return(A)
#the numbering is not perfectly ordered and varies in some places, so need to index it all to find the correct lines
def indexIFC(IFC):
A = []
for index, row in enumerate(IFC):
if re.findall('^#', row): #starts with a hash #
B = re.findall(r'\#\w+', row)[0]
A.append([B, index])
return(A)
def recurseThrough(inputList, IFC, checkedList, fullList, indexednumbersList):
for item in inputList:
for hashvalueList in indexednumbersList:
if item == hashvalueList[0]:
positionInIFC = hashvalueList[1]
if re.search('^'+item, IFC[positionInIFC]) and item not in checkedList: #if the row begins with the number item in the list
checkedList.append(item)
fullList.append(IFC[positionInIFC])
recurseThrough(re.findall(regexIFCnumbers, IFC[positionInIFC])[1:], IFC, checkedList, fullList, indexednumbersList) #recurses through the next list
return(fullList)
from os import system, name
def clear():
if name == 'nt':
_ = system('cls')
def runTheGUIDCheck(setValue):
inputValue = str(setValue)
print(inputValue)
clear()
try:
B1 = checkGUID(inputValue, x1) #This returns a list with for example [#122, #5, #7889]
checkedList = [] #the list of already checked items
fullList = []
indexedIFClist1 = indexIFC(x1)
#run the function with the initial input, sending in empty array as well as they should be empty/none at the start
outList1 = recurseThrough(B1, x1, [], [], indexedIFClist1)
for index, item in enumerate(outList1):
print(index, item.strip())
return None
except:
print("inserted GUID not found or didn't work")
#dialog
dialog = tk.Tk()
dialog.geometry('500x200')
t1 = tk.Label(dialog, text = 'Check GUID')
t1.grid(row = 0, column = 0, sticky = 'w')
testGUIDAttributes = tk.Entry(dialog, width = 40)
testGUIDAttributes.grid(row = 0, column = 1, columnspan = 50)
button = tk.Button(dialog, text='Run GUID', command = lambda: runTheGUIDCheck(testGUIDAttributes.get()))
button.grid(row = 5, column = 0, sticky = 'w')
dialog.mainloop()
If I select the file directly like this...
file1 = 'thefile.ifc'
instead of with the above this...
tk.Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
file1 = askopenfilename(initialdir=os.getcwd()) # show an "Open" dialog box and return the path to the selected file - this in the current directory where we'll start looking
then this issue doesn't come up and the command prompt will accept new commands after I close the dialog which is "created" at the end.
Since you have created two instances of Tk(): one in the line tk.Tk().withdraw() and one in the line dialog = tk.Tk(), so the line dialog.mainloop() will not return until both windows are closed. However you cannot close the withdrawn window because it is invisible.
You should create only one instance of Tk(), hide it and then show the file dialog. Then show it back and proceed as normal:
...
# create the main window and hide it initially
dialog = tk.Tk()
dialog.withdraw()
file1 = askopenfilename(initialdir=os.getcwd()) # show an "Open" dialog box and return the path to the selected file - this in the current directory where we'll start looking
...
# show back the main window
dialog.deiconify()
dialog.geometry('500x200')
...
dialog.mainloop()

How to make a dropdown list from an existing list in python (pandas and tkinter)

I want the user to submit their csv excel file and choose the columns from a dropdown menu he wants for analysis.
import pandas as pd
import os
import sys
from tkinter import *
root = Tk()
root.title('Eng3')
filepath = input('Enter filepath: ')
assert os.path.exists(filepath), "I did not find the file at, " + str(filepath)
f = open(filepath, 'r+')
print("Hooray we found your file!")
f.close()
file = pd.read_csv(filepath, encoding='latin1', delimiter=',')
column_list = file.columns.tolist()
print(column_list)
So I made the columns names from the excel file into a list. How can I make a dropdown menu from this list(column_list) to show all column names? When I tried:
tkvar = StringVar(column_list)
menu = OptionMenu(root, tvkar, column_list)
I get this error:
AttributeError: 'list' object has no attribute '_root'
I looked around and found this post How can I create a dropdown menu from a List in Tkinter?. Very useful
file = pd.read_csv(filepath, encoding='latin1', delimiter=',')
column_list = file.columns.tolist() #convert pandas dataframe to simple python list
OPTIONS = column_list #this is what solved my problem
master = Tk()
master.title('Eng3')
variable = StringVar(master)
variable.set(OPTIONS[0]) # default value
w = OptionMenu(master, variable, *OPTIONS)
w.pack()
def ok():
print ("value is:" + variable.get())
button = Button(master, text="OK", command=ok)
button.pack()

Python pass variable values in functions

So this is my full code. All I want is append excel files to one excel by sheets from a specific folder. It's GUI and has 3 buttons browse, append, and quit. How do i get path value from browsed folder(filename) ? thanks
from tkinter import *
from tkinter.filedialog import askdirectory
import tkinter as tk
import glob
import pandas as pd
import xlrd
root = Tk()
def browsefunc():
filename = askdirectory()
pathlabel.config(text=filename)
return filename
def new_window():
all_data = pd.DataFrame()
all_data1 = pd.DataFrame()
path = browsefunc()+"/*.xlsx"
for f in glob.glob(path):
df = pd.read_excel(f,sheetname='Scoring',header=0)
df1 = pd.read_excel(f,sheetname='Sheet1',header=0)
all_data = all_data.append(df,ignore_index=False)
all_data1 = all_data1.append(df1,ignore_index=True)
writer = pd.ExcelWriter('pandas_simple.xlsx', engine='xlsxwriter')
all_data.to_excel(writer, sheet_name='Scoring')
all_data1.to_excel(writer, sheet_name='Sheet1')
writer.save()
browsebutton = Button(root, text="Browse", command=browsefunc).pack()
Button(root, text='Append', command=new_window).pack()
Button(root, text='quit', command=root.destroy).pack()
pathlabel = Label(root)
pathlabel.pack()
mainloop()
It is not entirely clear what you are asking, so can you edit the question to be more specific?
I think you are trying to get the local variable filename (from inside the function browsefunc) able to be accessed outside the function as a global variable. Use return. This tutorial explains it nicely.
At the end of browsefunc you add
return filename
and when you call browsefunc you run
path = browsefunc()
That assigns the variable fdback to whatever you return from browsefunc. It can be an integer, float, string, or list etc.
So, final code is:
def browsefunc():
filename = askdirectory()
pathlabel.config(text=filename)
return filename
def new_window():
path = browsefunc()
I would recommend using more explicit variable and function names.

simple way to modify a tkFileDialog

I would like to modify the tkFileDialog to include a Checkbutton for "open this file after saving."
The boolean value of this Checkbutton would determine whether os.startfile() gets called on the file name returned from the dialog, or not.
Example: how could I set the variable openMeNow in:
import tkinter as tk
from os import path, startfile
import pandas as pd
def getOutputFileName(initDir,title="Save Output as",initFile="the_output",defaultExt=''):
root = tk.Tk()
root.lift()
root.attributes("-topmost", True)
root.withdraw()
fOut = tk.filedialog.asksaveasfilename(title=title,
initialdir=initDir,
initialfile=initFile,
defaultextension=defaultExt)
return fOut
outExcel = path.normpath( getOutputFileName(
title="Save Workbook as",
initDir='~/Documents',
initFile='the_workbook.xlsx',
defaultExt='.xlsx'
) )
# do some stuff that returns some results
results = pd.DataFrame({'a':[1,2],'b':[10,100],'c':[0,50]})
xlWriter = pd.ExcelWriter(outExcel, engine='xlsxwriter')
results.to_excel(xlWriter, sheet_name = 'The Results', index=False)
xlWriter.save()
if openMeNow: startfile(outExcel)
The question is sort of similar to this one, with the difference being that I'm trying to modify the filedialog class rather than add another dialog box.

Categories