Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python tkinter中的进度条不工作_Python_Tkinter_Progress Bar - Fatal编程技术网

Python tkinter中的进度条不工作

Python tkinter中的进度条不工作,python,tkinter,progress-bar,Python,Tkinter,Progress Bar,我正在写一个小应用程序来复制一些文件。我几乎做了我想要的所有东西,但有三件事: 1) “复制”选项处于运动状态时要移动的进度条。我可以展示它,但它不会反应 我用这个来表示: self.p = ttk.Progressbar(self, orient=HORIZONTAL, length=300, mode='indeterminate') self.p.grid(row=5) 然后在按下按钮后调用的另一个def中启动: self.p.start() shutil.copytree(sel

我正在写一个小应用程序来复制一些文件。我几乎做了我想要的所有东西,但有三件事:

1) “复制”选项处于运动状态时要移动的进度条。我可以展示它,但它不会反应

我用这个来表示:

self.p = ttk.Progressbar(self, orient=HORIZONTAL, length=300, mode='indeterminate')
self.p.grid(row=5)
然后在按下按钮后调用的另一个def中启动:

 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()
不幸的是,复制发生了,但条根本没有移动

2) 第二个问题与我在应用程序窗口底部显示的信息栏有关:

self.status = Label(self.master, text="Waiting for process to start...", bd=1, relief=SUNKEN, anchor=W)
self.status.pack(side=BOTTOM, fill=X)
然后,当在开始时调用相同的复制def时,我有:

self.status['text'] = "Files are being copyied, have patience ;)".format(self.status)
状态没有改变,这很奇怪,因为在这个def的末尾,我还有相同的命令来改变状态,这个命令有效:

self.status['text'] = "Files have been copyied".format(self.status)
3) 我似乎无法附加图片我已检查了各种不同的选项,但它们似乎都不起作用,此处显示的图片似乎试图显示某些内容(窗口变大),但图片不可见:

 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)
我有点不确定为什么会这样,以防万一,还有更多信息,我在这里发布完整的代码:

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()
编辑:
正如同时出现的其他问题一样,我似乎无法改变输入框周围按钮和边框的背景颜色。我读到这可能是因为使用MacOS平台,是吗?有什么解决办法吗?

我在我的一个老项目中压实了装载杆。我发现的唯一方法是在一个新线程中调用处理调用的进度条,并将工作密集型函数从这个线程调用到另一个新线程中

让一个单独的线程来处理UI线程以外的UI元素是不好的做法,包括启动和停止进度条;然而,它确实可以工作,我已经使用这个项目做了几个月的零问题相当繁重的处理

在这里,进度条在一个小脚本中工作,在W10 64位上使用Python 3.5.2

from tkinter import *
import tkinter.ttk as ttk
import threading
import time

class Main_Frame(object):
    def __init__(self, top=None):
        # save root reference
        self.top = top
        # set title bar
        self.top.title("Loading bar example")

        # start button calls the "initialization" function bar_init, you can pass a variable in here if desired
        self.start_button = ttk.Button(top, text='Start bar', command=lambda: self.bar_init(2500))
        self.start_button.pack()

        # the progress bar will be referenced in the "bar handling" and "work" threads
        self.load_bar = ttk.Progressbar(top)
        self.load_bar.pack()

        # run mainloop
        self.top.mainloop()

    def bar_init(self, var):
        # 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.start_bar, args=(var,))
        # start the bar handling thread
        self.start_bar_thread.start()

    def start_bar(self, var):
        # the load_bar needs to be configured for indeterminate amount of bouncing
        self.load_bar.config(mode='indeterminate', maximum=100, value=0)
        # 8 here is for speed of bounce
        self.load_bar.start(8)
        # start the work-intensive thread, again a var can be passed in here too if desired
        self.work_thread = threading.Thread(target=self.work_task, args=(var,))
        self.work_thread.start()
        # close the work thread
        self.work_thread.join()
        # stop the indeterminate bouncing
        self.load_bar.stop()
        # reconfigure the bar so it appears reset
        self.load_bar.config(value=0, maximum=0)

    def work_task(self, wait_time):
        for x in range(wait_time):
           time.sleep(0.001)

if __name__ == '__main__':
    # create root window
    root = Tk()
    # call Main_Frame class with reference to root as top
    Main_Frame(top=root)

Edit2:我已经找到了一种方法来制作图片和按钮背景:picture:render=PhotoImage(file=“az.gif”)img=Label(self,image=render,bg=“#e6e6”)img.image=render img.grid(row=8)和按钮,方法是添加“highlightbackground”:goButton=Button(self,text=“Go!”,command=self.copy,highlightbackground=“#e6e6”)但我仍然无法理解此进度条,没有任何提示?您应该在调用
self.p.start()
后尝试在新线程上启动复制函数。复制可能会阻止UI线程设置进度条的动画。我尝试过线程,但无法使其工作,即使使用线程时文件也没有被复制。可能是我实现错了,但我找不到正确的方法<代码>self.p.start()root.update_idletasks()用于范围(12)内的x:t=threading.Thread(target=self.copy2)t.deamon=True t.start()self.p.stop()然后更新所有
shutil.copytree(self.source\u direcotry0,self.cam0)
已移动到名为
copy2
的新的
def
。非常感谢您的帮助。我需要一些时间来消化并尝试它,但如果再次有疑问,我将返回。再次感谢!没问题,如果您还有任何问题,请随时发表意见,我会尽力帮助您的!:)