【发布时间】:2017-01-23 08:47:31
【问题描述】:
我正在编写一个小应用程序来复制一些文件。我做了几乎所有我想要的东西,但只有 3 件事:
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 平台,可能是这样吗?有什么解决方法吗?
【问题讨论】:
-
Edit2:我找到了一种方法来制作图片和按钮背景:图片:render = PhotoImage(file="az.gif") img = Label(self, image=render, bg="#E6E6E6") img.image = 通过添加“highlightbackground”渲染 img.grid(row=8) 和按钮: goButton = Button(self, text="Go!",command=self.copyy,highlightbackground=" #E6E6E6") 但是我还是看不懂这个进度条,一点提示都没有?
-
您应该在调用
self.p.start()后尝试在新线程上启动复制功能。复制可能会阻塞为进度条设置动画的 UI 线程。 -
我尝试过使用线程,但我无法让它工作,即使我使用线程时文件也没有被复制。可能我实施错了,但我找不到正确的方法。
self.p.start() root.update_idletasks() for x in range(12): t = threading.Thread(target=self.copyy2) t.deamon = True t.start() self.p.stop()然后所有的shutil.copytree(self.source_direcotry0, self.cam0)都被移动到了名为copyy2的新def。
标签: python tkinter progress-bar