Progress bar in tkinter not working
<p>I am writing a small app to copy some files. I have made almost everything that I wanted but 3 things:</p>

<p>1) Progress-bar to move while the copy option is in motion. I can display it but it won't react. </p>

<p>I am using this to show it:</p>

<pre><code>self.p = ttk.Progressbar(self, orient=HORIZONTAL, length=300, mode='indeterminate')
self.p.grid(row=5)
</code></pre>

<p>and then to initiate it in another def which is called upon a press of the button:</p>

<pre><code> self.p.start()

 shutil.copytree(self.source_direcotry0, self.cam0)
 shutil.copytree(self.source_direcotry1, self.cam1)
 shutil.copytree(self.source_direcotry2, self.cam2)

 self.p.stop()
</code></pre>

<p>Unfortunately the copying occurs but the bar doesn't move at all. </p>

<p>2) Second problem is connected to the information bar that I am displaying at the bottom of the app window:</p>

<pre><code>self.status = Label(self.master, text="Waiting for process to start...", bd=1, relief=SUNKEN, anchor=W)
self.status.pack(side=BOTTOM, fill=X)
</code></pre>

<p>And then when the same copying def is called at the beginning of it I have this: </p>

<pre><code>self.status['text'] = "Files are being copyied, have patience ;)".format(self.status)
</code></pre>

<p>And the status is not changed which is weird as at the end of this def I also have same command to change the status and this one works:</p>

<pre><code>self.status['text'] = "Files have been copyied".format(self.status)
</code></pre>

<p>3) I can't seem to attach a picture I have checked all kinds of different options and none of them seem to work, the one presented here seems like tries to display something (the window gets bigger) but the picture is not visible:</p>

<pre><code> self.img = ImageTk.PhotoImage(Image.open("az.png"))
 self.panel = Label(self, image=self.img, bg="#E6E6E6")
 self.display = self.img
 self.panel.grid(row=8)
</code></pre>

<p>I am a bit unsure why it is happening like that, just in case and also for more info I am posting here the complete code:</p>

<pre><code>from tkinter import *
from tkinter import ttk
import re
from tkinter import messagebox
from tkinter import filedialog
import ntpath
import os
import shutil
import tkinter.filedialog as fdialog
from send2trash import send2trash
from PIL import Image, ImageTk

#os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')


# Here, we are creating our class, Window, and inheriting from the Frame
# class. Frame is a class from the tkinter module. (see Lib/tkinter/__init__)

class Window(Frame):

    # Define settings upon initialization. Here you can specify
    def __init__(self, master=None):

        # parameters that you want to send through the Frame class. 
        Frame.__init__(self, master, bg="#E6E6E6")   

        #reference to the master widget, which is the tk window                 
        self.master = master

        #with that, we want to then run init_window, which doesn't yet exist
        self.init_window() 

    def copyy(self):

        self.status['text'] = "Files are being copyied, have patience ;)".format(self.status)


        self.source_direcotry0= '/Volumes/CAM0/DCIM/100HDDVR'
        self.source_direcotry1= '/Volumes/CAM1/DCIM/100HDDVR'
        self.source_direcotry2= '/Volumes/CAM2/DCIM/100HDDVR'
        self.source_direcotry3= '/Volumes/CAM3/DCIM/100HDDVR'
        self.source_direcotry4= '/Volumes/CAM4/DCIM/100HDDVR'
        self.source_direcotry5= '/Volumes/CAM5/DCIM/100HDDVR'
        self.source_direcotry6= '/Volumes/CAM6/DCIM/100HDDVR'
        self.source_direcotry7= '/Volumes/CAM7/DCIM/100HDDVR'
        self.source_direcotry8= '/Volumes/CAM8/DCIM/100HDDVR'
        self.source_direcotry9= '/Volumes/CAM9/DCIM/100HDDVR'
        self.source_direcotry10= '/Volumes/CAM10/DCIM/100HDDVR'
        self.source_direcotry11= '/Volumes/CAM11/DCIM/100HDDVR'

        self.path0="recording/CAM0"
        self.path1="recording/CAM1"
        self.path2="recording/CAM2"
        self.path3="recording/CAM3"
        self.path4="recording/CAM4"
        self.path5="recording/CAM5"
        self.path6="recording/CAM6"
        self.path7="recording/CAM7"
        self.path8="recording/CAM8"
        self.path9="recording/CAM9"
        self.path10="recording/CAM10"
        self.path11="recording/CAM11"

        self.cam0=os.path.join(self.Destination.get(), self.path0)
        self.cam1=os.path.join(self.Destination.get(), self.path1)
        self.cam2=os.path.join(self.Destination.get(), self.path2)
        self.cam3=os.path.join(self.Destination.get(), self.path3)
        self.cam4=os.path.join(self.Destination.get(), self.path4)
        self.cam5=os.path.join(self.Destination.get(), self.path5)
        self.cam6=os.path.join(self.Destination.get(), self.path6)
        self.cam7=os.path.join(self.Destination.get(), self.path7)
        self.cam8=os.path.join(self.Destination.get(), self.path8)
        self.cam9=os.path.join(self.Destination.get(), self.path9)
        self.cam10=os.path.join(self.Destination.get(), self.path10)
        self.cam11=os.path.join(self.Destination.get(), self.path11)

        self.p.start()

        shutil.copytree(self.source_direcotry0, self.cam0)
        shutil.copytree(self.source_direcotry1, self.cam1)
        shutil.copytree(self.source_direcotry2, self.cam2)
        # shutil.copytree(self.source_direcotry3, self.cam3)
        # shutil.copytree(self.source_direcotry4, self.cam4)
        # shutil.copytree(self.source_direcotry5, self.cam5)
        # shutil.copytree(self.source_direcotry6, self.cam6)
        # shutil.copytree(self.source_direcotry7, self.cam7)
        # shutil.copytree(self.source_direcotry8, self.cam8)
        # shutil.copytree(self.source_direcotry9, self.cam9)
        # shutil.copytree(self.source_direcotry10, self.cam10)
        # shutil.copytree(self.source_direcotry11, self.cam11)

        self.p.stop()

        self.status['text'] = "Files have been copyied".format(self.status)

    def deletee(self):
        send2trash('/Volumes/CAM0/DCIM')
        send2trash('/Volumes/CAM1/DCIM')
        send2trash('/Volumes/CAM2/DCIM')
        # send2trash('/Volumes/CAM3/DCIM')
        # send2trash('/Volumes/CAM4/DCIM')
        # send2trash('/Volumes/CAM5/DCIM')
        # send2trash('/Volumes/CAM6/DCIM')
        # send2trash('/Volumes/CAM7/DCIM')
        # send2trash('/Volumes/CAM8/DCIM')
        # send2trash('/Volumes/CAM9/DCIM')
        # send2trash('/Volumes/CAM10/DCIM')
        # send2trash('/Volumes/CAM11/DCIM')

        self.status['text'] = "Files have been moved to trash".format(self.status)


    def client_exit(self):
        exit()

    def about_popup(self):
        messagebox.showinfo("About", "This is software used to copy or delete files in bulk from the Absolute Zero VR camera")


    #Creation of init_window
    def init_window(self):

        self.Source=StringVar()
        self.Destination=StringVar()


        # changing the title of our master widget      
        self.master.title("AZ Data Extractor")

        # allowing the widget to take the full space of the root window
        self.pack(fill=BOTH, expand=1)

        #Creating the menu
        self.menubar = Menu(self.master)

        #Creating submenues
        self.filemenu = Menu(self.menubar, tearoff=0)
        self.filemenu.add_command(label="Exit", command=root.quit)
        self.menubar.add_cascade(label="File", menu=self.filemenu)

        self.helpmenu = Menu(self.menubar, tearoff=0)
        self.helpmenu.add_command(label="About", command=self.about_popup)
        self.menubar.add_cascade(label="Help", menu=self.helpmenu)

        #Displaying the menu
        root.config(menu=self.menubar)

        #Creating the  intro label
        l_instruction = Label(self, justify=CENTER, compound=TOP, text="Choose the destination for the copied files \n and press 'Go!' to start copyting", bg="#E6E6E6")
        l_instruction.grid(columnspan=2, ipady=10)

        l_instruction = Label(self, justify=CENTER, compound=TOP, text="Press 'Delete' to move all files \n from the camera to the trash", bg="#E6E6E6")
        l_instruction.grid(row=6, columnspan=2, ipady=10)

        # ttk.Style().configure('green/black.TButton', foreground='green', background='black')
        #Creating the button
        MyDestination=Entry(self, textvariable=self.Destination, bg="#E6E6E6")
        MyDestination.grid(row=2, columnspan=2, ipady=10)
        uploadButton = Button(self, text="Choose destination folder",command=lambda:self.Destination.set(fdialog.askdirectory()))
        uploadButton.grid(row=3, columnspan=2, ipady=10)
        goButton = Button(self, text="Go!",command=self.copyy)
        goButton.grid(row=4, columnspan=2, ipady=10)
        delButton = Button(self, text="Delete",command=self.deletee)
        delButton.grid(row=7, columnspan=2, ipady=10)

        self.p = ttk.Progressbar(self, orient=HORIZONTAL, length=300, mode='indeterminate')
        self.p.grid(row=5)

        self.img = ImageTk.PhotoImage(Image.open("az.png"))
        self.panel = Label(self, image=self.img, bg="#E6E6E6")
        self.display = self.img
        self.panel.grid(row=8)


        #resizing configuration
        self.grid_columnconfigure(0,weight=1)
        self.grid_columnconfigure(1,weight=1)
        self.grid_rowconfigure(0,weight=1)
        self.grid_rowconfigure(1,weight=1)
        self.grid_rowconfigure(2,weight=1)
        self.grid_rowconfigure(3,weight=1)
        self.grid_rowconfigure(4,weight=1)
        self.grid_rowconfigure(5,weight=1)
        self.grid_rowconfigure(6,weight=1)
        self.grid_rowconfigure(7,weight=1)
        self.grid_rowconfigure(8,weight=1)
        self.grid_rowconfigure(9,weight=1)
        self.grid_rowconfigure(10,weight=1)

        #status Bar
        self.status = Label(self.master, text="Waiting for process to start...", bd=1, relief=SUNKEN, anchor=W)
        self.status.pack(side=BOTTOM, fill=X)


# root window created. Here, that would be the only window, but you can later have windows within windows.
root = Tk()
root.resizable(width=False,height=False);
# root.configure(background='black');
# fm = Frame(root, width=300, height=200, bg="blue")
# fm.pack(side=TOP, expand=NO, fill=NONE)  
#root.geometry("230x340")



#creation of an instance
app = Window(root)

#mainloop 
root.mainloop()
</code></pre>

<p>Edit:
Just as and additional problem that came up in the mean time I can't seem to change background colour of the buttons and the frames around entry field. I read up it could be because using MacOS platform, could that be? Any workarounds?</p>

<p>So I have used your code to make the improvements in mine and it works :) Unfortunately there is a "but". So the progress bar is nicely moving while files are being copied. What is still not perfect that after the button is pressed to execute the coping there is quite substantial delay time before the copying start. It is long enough that average user might start suspecting program has crashed. I think is has too be something connect to how threads start but I made couple of combinations and non of them improved the issue. I am posting whole code as I though it will be easier for you to see what is going on. Thank in advance @Joules!</p>

<p>Here is the code:</p>

<pre><code>from tkinter import *
from tkinter import ttk
import re
from tkinter import messagebox
from tkinter import filedialog
import ntpath
import os
import shutil
import tkinter.filedialog as fdialog
from send2trash import send2trash
from PIL import Image, ImageTk
from threading import Thread
import threading


os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')


# Here, we are creating our class, Window, and inheriting from the Frame
# class. Frame is a class from the tkinter module. (see Lib/tkinter/__init__)

class Window(Frame):

    # Define settings upon initialization. Here you can specify
    def __init__(self, master=None):

        # parameters that you want to send through the Frame class. 
        Frame.__init__(self, master, bg="#E6E6E6")   

        #reference to the master widget, which is the tk window                 
        self.master = master

        #with that, we want to then run init_window, which doesn't yet exist
        self.init_window() 

    def bar_init(self):
        # first layer of isolation, note var being passed along to the self.start_bar function
        # target is the function being started on a new thread, so the "bar handler" thread
        self.start_bar_thread = threading.Thread(target=self.copyy, args=())
        # start the bar handling thread
        self.start_bar_thread.start()

    def copyy(self):
        root.update_idletasks()
        self.status['text'] = "Files are being copyied, have patience ;)".format(self.status)


        self.source_direcotry0= '/Volumes/CAM0/DCIM/100HDDVR'
        self.source_direcotry1= '/Volumes/CAM1/DCIM/100HDDVR'
        self.source_direcotry2= '/Volumes/CAM2/DCIM/100HDDVR'
        self.source_direcotry3= '/Volumes/CAM3/DCIM/100HDDVR'
        self.source_direcotry4= '/Volumes/CAM4/DCIM/100HDDVR'
        self.source_direcotry5= '/Volumes/CAM5/DCIM/100HDDVR'
        self.source_direcotry6= '/Volumes/CAM6/DCIM/100HDDVR'
        self.source_direcotry7= '/Volumes/CAM7/DCIM/100HDDVR'
        self.source_direcotry8= '/Volumes/CAM8/DCIM/100HDDVR'
        self.source_direcotry9= '/Volumes/CAM9/DCIM/100HDDVR'
        self.source_direcotry10= '/Volumes/CAM10/DCIM/100HDDVR'
        self.source_direcotry11= '/Volumes/CAM11/DCIM/100HDDVR'

        self.path0="recording/CAM0"
        self.path1="recording/CAM1"
        self.path2="recording/CAM2"
        self.path3="recording/CAM3"
        self.path4="recording/CAM4"
        self.path5="recording/CAM5"
        self.path6="recording/CAM6"
        self.path7="recording/CAM7"
        self.path8="recording/CAM8"
        self.path9="recording/CAM9"
        self.path10="recording/CAM10"
        self.path11="recording/CAM11"

        self.cam0=os.path.join(self.Destination.get(), self.path0)
        self.cam1=os.path.join(self.Destination.get(), self.path1)
        self.cam2=os.path.join(self.Destination.get(), self.path2)
        self.cam3=os.path.join(self.Destination.get(), self.path3)
        self.cam4=os.path.join(self.Destination.get(), self.path4)
        self.cam5=os.path.join(self.Destination.get(), self.path5)
        self.cam6=os.path.join(self.Destination.get(), self.path6)
        self.cam7=os.path.join(self.Destination.get(), self.path7)
        self.cam8=os.path.join(self.Destination.get(), self.path8)
        self.cam9=os.path.join(self.Destination.get(), self.path9)
        self.cam10=os.path.join(self.Destination.get(), self.path10)
        self.cam11=os.path.join(self.Destination.get(), self.path11)

        self.p.start(1)


        self.work_thread = threading.Thread(target=self.copyy2, args=())
        self.work_thread.start()
        self.work_thread.join()


        self.p.stop()

        self.status['text'] = "Files have been copyied".format(self.status)

    def copyy2(self):

        shutil.copytree(self.source_direcotry0, self.cam0)
        shutil.copytree(self.source_direcotry1, self.cam1)
        shutil.copytree(self.source_direcotry2, self.cam2)
        shutil.copytree(self.source_direcotry3, self.cam3)
        shutil.copytree(self.source_direcotry4, self.cam4)
        shutil.copytree(self.source_direcotry5, self.cam5)
        shutil.copytree(self.source_direcotry6, self.cam6)
        shutil.copytree(self.source_direcotry7, self.cam7)
        shutil.copytree(self.source_direcotry8, self.cam8)
        shutil.copytree(self.source_direcotry9, self.cam9)
        shutil.copytree(self.source_direcotry10, self.cam10)
        shutil.copytree(self.source_direcotry11, self.cam11)

    def deletee(self):
        send2trash('/Volumes/CAM0/DCIM')
        send2trash('/Volumes/CAM1/DCIM')
        send2trash('/Volumes/CAM2/DCIM')
        send2trash('/Volumes/CAM3/DCIM')
        send2trash('/Volumes/CAM4/DCIM')
        send2trash('/Volumes/CAM5/DCIM')
        send2trash('/Volumes/CAM6/DCIM')
        send2trash('/Volumes/CAM7/DCIM')
        send2trash('/Volumes/CAM8/DCIM')
        send2trash('/Volumes/CAM9/DCIM')
        send2trash('/Volumes/CAM10/DCIM')
        send2trash('/Volumes/CAM11/DCIM')

        self.status['text'] = "Files have been moved to trash".format(self.status)


    def client_exit(self):
        exit()

    def about_popup(self):
        messagebox.showinfo("About", "This is software used to copy or delete files in bulk from the Absolute Zero VR camera")


    #Creation of init_window
    def init_window(self):

        self.Source=StringVar()
        self.Destination=StringVar()


        # changing the title of our master widget      
        self.master.title("AZ Data Extractor")

        # allowing the widget to take the full space of the root window
        self.pack(fill=BOTH, expand=1)

        #Creating the menu
        self.menubar = Menu(self.master)

        #Creating submenues
        self.filemenu = Menu(self.menubar, tearoff=0)
        self.filemenu.add_command(label="Exit", command=root.quit)
        self.menubar.add_cascade(label="File", menu=self.filemenu)

        self.helpmenu = Menu(self.menubar, tearoff=0)
        self.helpmenu.add_command(label="About", command=self.about_popup)
        self.menubar.add_cascade(label="Help", menu=self.helpmenu)

        #Displaying the menu
        root.config(menu=self.menubar)

        #Creating the  intro label
        l_instruction = Label(self, justify=CENTER, compound=TOP, text="Choose the destination for the copied files \n and press 'Go!' to start copyting", bg="#E6E6E6")
        l_instruction.grid(columnspan=2, ipady=10)

        l_instruction = Label(self, justify=CENTER, compound=TOP, text="Press 'Delete' to move all files \n from the camera to the trash", bg="#E6E6E6")
        l_instruction.grid(row=6, columnspan=2, ipady=10)

        #Creating the button
        MyDestination=Entry(self, textvariable=self.Destination,highlightbackground="#E6E6E6")
        MyDestination.grid(row=2, columnspan=2, ipady=10)
        uploadButton = Button(self, text="Choose destination folder",command=lambda:self.Destination.set(fdialog.askdirectory()),highlightbackground="#E6E6E6")
        uploadButton.grid(row=3, columnspan=2, ipady=10)
        goButton = Button(self, text="Go!",command=self.bar_init,highlightbackground="#E6E6E6")
        goButton.grid(row=4, columnspan=2, ipady=10)
        delButton = Button(self, text="Delete",command=self.deletee,highlightbackground="#E6E6E6")
        delButton.grid(row=7, columnspan=2, ipady=10)

        s = ttk.Style()
        s.theme_use('alt')
        s.configure("grey.Horizontal.TProgressbar", troughcolor='#E6E6E6', background='gray', bordercolor='#E6E6E6')

        self.p = ttk.Progressbar(self, style="grey.Horizontal.TProgressbar", orient=HORIZONTAL, length=300, mode='indeterminate')
        self.p.grid(row=5)

        render = PhotoImage(file="az.gif")
        img = Label(self, image=render, bg="#E6E6E6")
        img.image = render
        img.grid(row=10)

        space = Label(self, bg="#E6E6E6")
        space.grid(row=8)
        space2 = Label(self, bg="#E6E6E6")
        space2.grid(row=9)
        space3 = Label(self, bg="#E6E6E6")
        space3.grid(row=11)


        #resizing configuration
        self.grid_columnconfigure(0,weight=1)
        self.grid_columnconfigure(1,weight=1)
        self.grid_rowconfigure(0,weight=1)
        self.grid_rowconfigure(1,weight=1)
        self.grid_rowconfigure(2,weight=1)
        self.grid_rowconfigure(3,weight=1)
        self.grid_rowconfigure(4,weight=1)
        self.grid_rowconfigure(5,weight=1)
        self.grid_rowconfigure(6,weight=1)
        self.grid_rowconfigure(7,weight=1)
        self.grid_rowconfigure(8,weight=1)
        self.grid_rowconfigure(9,weight=1)
        self.grid_rowconfigure(10,weight=1)
        self.grid_rowconfigure(11,weight=1)


        #status Bar
        self.status = Label(self.master, text="Waiting for process to start...", bd=1, relief=SUNKEN, anchor=W)
        self.status.pack(side=BOTTOM, fill=X)


# root window created. Here, that would be the only window, but you can later have windows within windows.
root = Tk()
root.resizable(width=False,height=False);
#root.geometry("230x340")



#creation of an instance
app = Window(root)

#mainloop 
root.mainloop()
</code></pre>

python tkinter progress-bar