Search code examples
pythonuser-interfacetkintercustomtkinterpyperclip

Error when trying to open txt file in Python


I'm making an app using Custom Tkinter, and in this app I want to create buttons based on .txt files in a folder, and make the buttons copy the content of these .txt files. Simple copy / paste buttons.

This class for the buttons worked GREAT on my mac, but now on windows it gives me error.

I've checked multiple discussions with no luck. example tried "encoding="utf-8"", didn't work.

class CopyPaste(customtkinter.CTkScrollableFrame):

    def __init__(self, master):
        super().__init__(master)

        global counter
        counter = 1

        self.Header = customtkinter.CTkLabel(self, text="Template Answers",
                                             font=("Arial", 20))
        self.Header.grid(row=0, column=0, padx=10, pady=10, sticky="w")

        target_directory = "C:/ToolKit Files"

        def read_file(file_path):
            with open(file_path, "r") as file:
                content = file.read()
            return content

        def create_button(self, file_path):

            file_name = os.path.basename(file_path)

            def on_button_click():
                pyperclip.copy(read_file(file_path))

            button = customtkinter.CTkButton(self, text=file_name, command=on_button_click)
            button.grid(row=counter, column=0, padx=10, pady=5)

        def create_buttons(self, target_directory):

            file_names = [file for file in os.listdir(target_directory) if file.endswith('.txt')]
            for file_name in file_names:
                global counter
                file_path = os.path.join(target_directory, file_name)
                create_button(self, file_path)
                counter += 1

        create_buttons(self, target_directory)

After running this script I receive:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\USER\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "C:\Users\USER\PycharmProjects\SidekickToolKit\venv\lib\site-packages\customtkinter\windows\widgets\ctk_button.py", line 554, in _clicked
    self._command()
  File "C:\Users\USER\PycharmProjects\SidekickToolKit\main.py", line 162, in on_button_click
    pyperclip.copy(read_file(file_path))
  File "C:\Users\USER\PycharmProjects\SidekickToolKit\main.py", line 154, in read_file
    content = file.read()
  File "C:\Users\USER\AppData\Local\Programs\Python\Python39\lib\encodings\cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 448: character maps to <undefined>

Help is greatly appreciated :D


Solution

  • your code looks fine, I think what is left to be done which triggers the error, UnicodeDecodeErrortraceback is for you to tell Python theencoding` to use to read the file.

    Here is the update of your code:

    
    def read_file(file_path):
           # wrap the entire code snippet in a try-catch block
           try:
               with open(file_path, "r", encoding="utf-8") as file:
                   content = file.read()
               return content
          # catch the error if any
           except UnicodeDecodeError:
               return f'Error reading file {file}.'
    

    I believe your code should work now since you have set the encoding to utf-8. If the encoding set to utf-8did not work after you must have updated your os, I use Linux though, then you can set this —errors='ignore' to where we put the encoding parameter. Goodluck mate.