error

>>> %Run mpremote_gui.py
Traceback (most recent call last):
  File "G:\My Drive\python\mpremote_gui.py", line 127, in <module>
    file_listbox = ctk.CTkListbox(app, height=200, noheadings=False, selectmode="single")  # Use CtkListbox for selection
AttributeError: module 'customtkinter' has no attribute 'CTkListbox'
>>> 
running this code
import subprocess
import tkinter
import customtkinter as ctk
from tkinter import messagebox, filedialog
import os
import re  # Importing regex for stripping leading numbers

def list_files():
    try:
        # Run the mpremote command to list files on the Pico
        result = subprocess.run(
            ["mpremote", "fs", "ls"],
            capture_output=True,
            text=True,
            check=True
        )

        print("Command executed successfully")  # Debugging output

        # Clear current listbox
        file_listbox.delete(0, "end")  # Clear the display in the listbox

        # Insert the result into the listbox, removing leading numbers
        for line in result.stdout.strip().split('\n'):
            file_name = line.strip()
            # Strip leading numbers and spaces
            cleaned_name = re.sub(r'^\d+\s*', '', file_name)  # Remove leading numbers and spaces
            file_listbox.insert("end", cleaned_name)  # Insert the cleaned name into the listbox

    except subprocess.CalledProcessError as e:
        error_message = f"Failed to list files:\n"
        error_message += f"Return Code: {e.returncode}\n"
        error_message += f"STDOUT: {e.stdout}\n"
        error_message += f"STDERR: {e.stderr}"
        messagebox.showerror("Error", error_message)
    except Exception as e:
        messagebox.showerror("Error", f"An unexpected error occurred: {str(e)}")

def upload_file():
    # Open a file dialog to select a file
    file_path = filedialog.askopenfilename()
    if file_path:
        file_name = os.path.basename(file_path)

        print(f"Uploading '{file_path}' to Pico as '/{file_name}'")

        if not os.path.exists(file_path):
            messagebox.showerror("Error", f"The file does not exist at: {file_path}")
            return

        try:
            # Run mpremote cp to upload the selected file to the Pico
            command = ["mpremote", "fs", "cp", file_path, f":/{file_name}"]
            print(f"Executing command: {' '.join(command)}")

            result = subprocess.run(
                command,
                capture_output=True,
                text=True,
                check=True
            )

            messagebox.showinfo("Success", f"Uploaded '{file_name}' to Pico successfully!")
            list_files()  # Refresh the file list after uploading

        except subprocess.CalledProcessError as e:
            error_message = f"Failed to upload file:\n"
            error_message += f"Return Code: {e.returncode}\n"
            error_message += f"STDOUT: {e.stdout}\n"
            error_message += f"STDERR: {e.stderr}"
            messagebox.showerror("Error", error_message)

def view_file_contents(event):
    try:
        # Get the selected file from the listbox
        selected_file = file_listbox.get(file_listbox.curselection())

        print(f"Selected file: '{selected_file}'")  # Debugging output

        # Retrieve the file's contents using mpremote cat
        command = ["mpremote", "fs", "cat", f":{selected_file}"]
        print(f"Executing command: {' '.join(command)}")  # Debugging the command

        result = subprocess.run(
            command,
            capture_output=True,
            text=True,
            check=True
        )

        # Clear the text area and display the contents
        text_area.delete("1.0", ctk.END)
        text_area.insert(ctk.END, result.stdout)

    except IndexError:
        messagebox.showerror("Error", "No file selected.")
    except subprocess.CalledProcessError as e:
        error_message = f"Failed to read file contents:\n"
        error_message += f"Return Code: {e.returncode}\n"
        error_message += f"STDOUT: {e.stdout}\n"
        error_message += f"STDERR: {e.stderr}"
        messagebox.showerror("Error", error_message)

# Create the main window
app = ctk.CTk()  # Use CustomTkinter's application class
app.title("Raspberry Pi Pico File Management")

# Set background color for the main window
app.configure(bg="#f0f8ff")

# Create a frame for the buttons on the left side
button_frame = ctk.CTkFrame(app, fg_color="#add8e6")
button_frame.grid(row=0, column=0, sticky='ns', padx=10, pady=10)

# Button color settings
button_bg = "#87cefa"  # Sky blue
button_fg = "black"  # Text color

# Buttons
list_button = ctk.CTkButton(button_frame, text="List Files", command=list_files, width=200, fg_color=button_bg, text_color=button_fg)
list_button.grid(row=0, column=0, pady=5, sticky='ew')

upload_button = ctk.CTkButton(button_frame, text="Upload File", command=upload_file, width=200, fg_color=button_bg, text_color=button_fg)
upload_button.grid(row=1, column=0, pady=5, sticky='ew')

# Bind the mouse click event to the file listbox to view file contents
file_listbox = ctk.CTkListbox(app, height=200, noheadings=False, selectmode="single")  # Use CtkListbox for selection
file_listbox.grid(row=0, column=1, padx=10, pady=10, sticky='nsew')  # Use grid layout
file_listbox.bind("<Button-1>", view_file_contents)  # Bind left mouse click to the view function

# Create a frame for displaying file contents
content_frame = ctk.CTkFrame(app, fg_color="#f0f8ff")  # Frame for the content area
content_frame.grid(row=1, column=0, columnspan=2, padx=10, pady=10, sticky='ew')  # Use grid layout

# Create a text area for file contents
text_area = ctk.CTkTextbox(content_frame, fg_color="#f5f5f5", text_color="#000000")
text_area.pack(fill=ctk.BOTH, expand=True, padx=10, pady=10)

# Configure the main grid layout
app.grid_rowconfigure(0, weight=1)  # Make the row with buttons expandable
app.grid_rowconfigure(1, weight=1)  # Make the content area expandable
app.grid_columnconfigure(1, weight=1)  # Allow the file list column to expand

# Run the application
app.mainloop()