i'm struggling with my program. I'm using tkinter OpenFileDialog (AskOpenFile) to open .txt file and ploting it. I need open more than one file at once and work with these files. My function AskOpenFile works well, but i want to use AskOpenFiles function, so i can work with many files at once, resp. create one plot out of more .txt files. Can anybody please help me? I get following message: Exception in Tkinter callback Traceback (most recent call last):
File "C:\Users\m.salik\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py", line 1962, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "C:\Users\m.salik\PycharmProjects\pythonProject\Polycontact\GUI_main.py", line 95, in select_file
Analysis_frame.analysis(self)
File "C:\Users\m.salik\PycharmProjects\pythonProject\Polycontact\GUI_main.py", line 19, in analysis
data = pd.read_csv(data_raw, sep=";", skiprows=[0], low_memory=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\m.salik\PycharmProjects\pythonProject\.venv\Lib\site-packages\pandas\io\parsers\readers.py", line 948, in read_csv
return _read(filepath_or_buffer, kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\m.salik\PycharmProjects\pythonProject\.venv\Lib\site-packages\pandas\io\parsers\readers.py", line 611, in _read
parser = TextFileReader(filepath_or_buffer, **kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\m.salik\PycharmProjects\pythonProject\.venv\Lib\site-packages\pandas\io\parsers\readers.py", line 1448, in __init__
self._engine = self._make_engine(f, self.engine)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\m.salik\PycharmProjects\pythonProject\.venv\Lib\site-packages\pandas\io\parsers\readers.py", line 1720, in _make_engine
raise ValueError(msg)
ValueError: Invalid file path or buffer object type: <class 'list'>
My code:
```` import tkinter as tk
from tkinter import *
from tkinter import messagebox
from tkinter import filedialog as fd
import pandas as pd
import matplotlib.pyplot as plt
class Analysis_frame(tk.LabelFrame):
def __init__(self, container):
super().__init__(container)
self.configure(text="Analysis", relief="ridge", font=("Verdana", 10), borderwidth=1, border=3)
self.__create_widgets()
def analysis(self):
global Test_Start, Test_End, Duration, Duration_End, Temperature, MinTemp, MaxTemp, Start_Time, End_Time
global Current_IN_max, Current_IN_min, MaxValue_I_IN_max, MinValue_I_IN_max
global data
data = pd.read_csv(data_raw, sep=";", skiprows=[0], low_memory=False)
# print(data_raw.columns)
Test_Start = data.iloc[:, 0].values[0]
Test_End = data.iloc[:, 0].values[-1]
Start_Time = data.iloc[:, 1].values[0]
End_Time = data.iloc[:, 1].values[-1]
Duration = data.iloc[:, 3]
Duration_End = data.iloc[:, 3].values[-1]
Temperature = data.iloc[:, 4]
MinTemp = Temperature.min()
MaxTemp = Temperature.max()
Humidity = data.iloc[:, 5]
Supply_IN_max = data.iloc[:, 8]
Supply_IN_min = data.iloc[:, 9]
Current_IN_max = data.iloc[:, 12]
Current_IN_min = data.iloc[:, 13]
Voltage_OUT_max = data.iloc[:, 20]
pd.set_option("display.max_rows", 20000)
##### Temperature diagram #####
def __create_plot_temp(self):
fig, ax1 = plt.subplots(facecolor="white", figsize=(17,10), dpi=100)
ax1.set_title("Temperature diagram", font="Verdana", fontsize=11)
ax1.set_facecolor("whitesmoke")
plt.subplots_adjust(left=0.05, right=0.95, top=0.98, bottom=0.15)
ax1.set_ylim(bottom=0, top=1)
ax1.set_xlim(0,Duration_End)
ax2 = ax1.twinx()
ax2.set_ylim(bottom=MinTemp-10, top=MaxTemp+15)
ax1.minorticks_on()
plt.minorticks_on()
ax1.set_ylabel("Current [A]").set_fontsize(10)
ax2.set_ylabel("Temperature [°C]").set_fontsize(10)
ax1.set_xlabel("Test duration [h]").set_fontsize(10)
sample1, = ax1.plot(Duration, Current_IN_max, label="IGSS1", color="green", marker=".", markersize=2,
mouseover=True, linewidth=0.2, visible=True, alpha=0.5)
sample2, = ax1.plot(Duration, Current_IN_min, label="IGSS2", color="orange", marker=".", markersize=2,
mouseover=True, linewidth=0.2, visible=True, alpha=0.5)
temp, = ax2.plot(Duration, Temperature, label="Temperature", color="red", linewidth=0.8, alpha=0.7)
plt.figtext(0.05,0.10,f"Test start: {Test_Start +" "+ Start_Time}", fontfamily="verdana", fontsize=10)
plt.figtext(0.85,0.10, f"Test end: {Test_End +" "+ End_Time}", fontfamily="verdana", fontsize=10)
plt.show()
def __create_widgets(self):
tk.Button(self, text="Temperature" "\n" "diagram", font=("Verdana", 8), command=self.__create_plot_temp).grid(
column=0, row=0, sticky=tk.S)
for widget in self.winfo_children(): # spacings for all widgets within the frame
widget.grid(padx=5, pady=5)
class Button_frame(tk.LabelFrame): # create frame
def __init__(self, container):
super().__init__(container)
self.configure(text="Files", font=("Verdana", 10), relief="ridge", borderwidth=1, border=3)
self.__create_widgets()
def select_file(self): # function for opening the csv files, command for open_file button
global data_raw
filetypes = (
("textfiles", ".txt"),
)
file = fd.askopenfiles(
filetypes=filetypes,
mode="r+",
title="Open file",
initialdir="/",
)
if file is not None:
data_raw = file
Analysis_frame.analysis(self)
messagebox.showinfo("Data", "Data loaded succesfull!")
else:
messagebox.showinfo("Data", "No data loaded!")
def __create_widgets(self): # create buttons within the frame
open_file = tk.Button(self, text="Open csv file", font=("Verdana", 8), command=self.select_file)
open_file.grid(column=0, row=0, sticky=N)
exit = tk.Button(self, text="Close", font=("Verdana", 8), command=quit)
exit.grid(column=1, row=0, sticky=N)
for widget in self.winfo_children(): # spacings for all widgets within the frame
widget.grid(padx=5, pady=5)
class Main_window(tk.Tk):
def __init__(self):
super().__init__()
self.title("Analysis")
self.geometry("600x500")
#self.attributes("-toolwindow", True)
self.__create_widgets()
def __create_widgets(self):
analysis = Analysis_frame(self)
analysis.grid(column=0, row=2, sticky=NW)
buttons = Button_frame(self)
buttons.grid(column=0, row=1, sticky=NW)
for widget in self.winfo_children(): # spacings for all widgets within the main window
widget.grid(padx=5, pady=5)
if __name__ == "__main__":
app = Main_window()
app.mainloop()```
The issue is here:
file = fd.askopenfiles(
filetypes=filetypes,
mode="r+",
title="Open file",
initialdir="/",
)
askopenfiles
returns a list
of files (even if you only select one file), so that's why you're getting the error
ValueError: Invalid file path or buffer object type: <class 'list'>
(you're passing a list
to your analysis
method, but pd.read_csv
expects a file path or buffer)
If you want to open and process the selected files one after another, you need to iterate over the list returned by askopenfiles
like so
def select_file(self):
global data_raw
filetypes = (("textfiles", ".txt"),)
files = fd.askopenfiles( # changed this to 'files' since it's a list of multiple files
filetypes=filetypes,
mode="r+",
title="Open file",
initialdir="/",
)
for file in files: # iterate over the list of files
if file is not None:
data_raw = file
Analysis_frame.analysis(self)
messagebox.showinfo("Data", "Data loaded succesfull!")
else:
messagebox.showinfo("Data", "No data loaded!")
Also, as a recommendation, I'd be careful with all those globals. It's far more likely that you're better off using class attributes, e.g. self.data_raw
if you need to access variable values from different methods within your classes or if you're passing values between classes.