[英]Tkinter updating label after using pyinstaller
When I run the .py file, the program runs fine as in self.error updates as robocopy is running.当我运行 .py 文件时,程序运行良好,就像在 robocopy 运行时的 self.error 更新中一样。 However after I've changed it to a .exe file using
pyinstaller -F -w Shortcutsv2.1.py
I've noticed that the tkinter label which shows how many files it has updated (self.error) doesn't update until after the terminal is closed.但是,在我使用
pyinstaller -F -w Shortcutsv2.1.py
将其更改为 .exe 文件后,我注意到显示它已更新的文件数量(self.error)的 tkinter 标签直到之后才会更新终端已关闭。 Is there a way to have it work like the script?有没有办法让它像脚本一样工作? I'm assuming this is due to a setting in pyinstaller but I may be wrong
我假设这是由于 pyinstaller 中的设置,但我可能错了
CODE:代码:
from subprocess import PIPE, run
import tkinter as tk
from tkinter import ttk
import tkinter.messagebox as mb
import tkinter.font as tkFont
from os import path
from os import listdir
from os import mkdir
from os import walk
from glob import glob
import threading
import pandas as pd
from datetime import datetime
class Windows(threading.Thread):
def __init__(self, master):
threading.Thread.__init__(self)
self.width = 400
self.height = 150
master.geometry(f"{self.width}x{self.height}")
master.title("Shortcuts")
#master.iconbitmap(r'ip.ico')
self.frame = tk.Frame(master,bg="white")
self.frame.place(relx=0, rely=0, relwidth=1, relheight=1)
self.font = ('Helvetica', '10')
#Source path label and text entry
self.srcLabel = tk.Label(self.frame, text="Source Path:", font=self.font, bg="white")
self.srcLabel.place(relx=0.001, rely=0.026, relwidth=0.31, relheight=0.2)
self.srcEntry = tk.Entry(self.frame, font=self.font, bg="white")
self.srcEntry.place(relx=0.31, rely=0.026, relwidth=0.68, relheight=0.2)
#Destination path label and text entry
self.dstLabel = tk.Label(self.frame, text="Destination Path:", font=self.font, bg="white")
self.dstLabel.place(relx=0.001, rely=0.246, relwidth=0.31, relheight=0.2)
self.dstEntry = tk.Entry(self.frame, font=self.font, bg="white")
self.dstEntry.place(relx=0.31, rely=0.246, relwidth=0.68, relheight=0.2)
#New Folder to be created label and text entry
self.nfLabel = tk.Label(self.frame, text="New Folder:", font=self.font, bg="white")
self.nfLabel.place(relx=0.001, rely=0.466, relwidth=0.31, relheight=0.2)
self.nfEntry = tk.Entry(self.frame, font=self.font, bg="white")
self.nfEntry.place(relx=0.31, rely=0.466, relwidth=0.68, relheight=0.2)
#Submit
self.submit = tk.Button(self.frame, text="Submit", bg="white", font=self.font,
command = self.threadCmd)
self.submit.place(relx=0.5, rely=0.733, relwidth=0.3, relheight=0.2)
#Errors
self.error = tk.Label(self.frame, text="", font=self.font, bg="white", fg="red")
self.error.place(relx=0.001, rely=0.733, relwidth=0.53, relheight=0.2)
def findFile(self, dirPath):
#finds the full path of all files including within the subdirectories
i = 0
temp = []
filesInDir = [f"{dirPath}\\{a}" for a in listdir(dirPath)]
for a in filesInDir:
i += 1
fullPath = path.join(dirPath, a)
if path.isdir(fullPath):
temp = temp + self.findFile(fullPath)
else:
temp.append(fullPath)
return temp
def lowestFolder(self, direc):
#finds the lowest last folder if any and creates the ~~~~.txt in there to ensure it is the last file to be copied
subdir = [x[0] for x in walk(direc)]
subdir.sort()
if subdir[-1] == direc:
f = open(path.join(direc,"~~~~.txt"),"w+")
f.close()
else:
self.lowestFolder(str(path.join(direc,subdir[-1])))
def Run(self):
if not path.exists(self.srcEntry.get()):
self.error.config(text="Can't find src path", fg="red")
elif not path.exists(self.dstEntry.get()):
self.error.config(text="Can't find dstn path", fg="red")
else:
dest = self.dstEntry.get() + "\\" + self.nfEntry.get()
if path.isdir(dest):
self.error.config(text="Folder Exists", fg="red")
else:
self.error.config(text="")
self.filename = "logs.xlsx"
self.listOfFiles = glob(path.join(".",self.filename))
self.lowestFolder(self.srcEntry.get())
filesTransferred = self.findFile(self.srcEntry.get())
length = len(filesTransferred)
mkdir(dest)
date = datetime.now()
run(f"start cmd /K RoboCopy.exe \"{self.srcEntry.get()}\" \"{dest}\" *.* /E /Z", stdout=PIPE, stdin=PIPE, stderr=PIPE, shell=True)
#Checks if all files have been transferred before moving on
i = 0
while(i < length):
fullPath = filesTransferred[i].replace(self.srcEntry.get(), dest)
if path.exists(fullPath):
i += 1
self.error.config(text=f'Transferring file(s): {i}/{length}', fg='black')
temp2 = self.findFile(dest)
temp2 = [x.replace(dest, "..") for x in temp2]
if length == len(temp2):
#Creates log file if not created
if not self.listOfFiles:
writer = pd.ExcelWriter(self.filename, engine='xlsxwriter')
writer.save()
df = pd.read_excel(self.filename)
#creates file if it doesn't exist else apppends
df2 = pd.DataFrame({"Started" : [date],
"Source": [self.srcEntry.get()],
"Destination": [self.dstEntry.get()],
"Files": [", ".join(temp2)]})
df = df.append(df2, sort=False)
df.to_excel(self.filename, index=False)
self.error.config(text="Files copied successfully.", fg="green")
#IF ROBOCOPY FREEZES WHEN YOU CLICK ON IT THEN JUST PRESS TAB AND IT SHOULD RESUME
else:
self.error.config(text="All files were not copied.", fg="red")
def threadCmd(self):
self.result = None
y = threading.Thread(target=self.Run)
y.start()
if __name__ == "__main__":
root = tk.Tk()
x = threading.Thread(target=Windows, args=(root,))
x.start()
x.join
root.mainloop()
EDIT 1编辑 1
" There are couple problems here. 1. Inherit class Windows(threading.Thread): but don't use this object. 2. Passing a class definition as .Thread(target=Windows. 3. Useless x.join without calling it. 4. Accessing tkinter objects, egself.srcEntry.get(), from a Thread. " "这里有几个问题。1. 继承类 Windows(threading.Thread): 但不要使用这个对象。2. 将类定义作为 .Thread(target=Windows. 3. 无用的 x.join 不调用它。 4.从线程访问tkinter对象,例如self.srcEntry.get()。 ”
I've changed the code to the below so now: 1) Can't make this change as I'm using .start() 2) Changed this to an instance 3) called the function 4) Didn't make this change as wasn't sure what the issue was.我现在已将代码更改为以下代码:1) 无法进行此更改,因为我正在使用 .start() 2) 将此更改为实例 3) 调用函数 4) 未进行此更改不知道是什么问题。 Needs more clarification
需要更多说明
The issue which I had posted for still persists however I appreciate the help to tidy up my code :)我发布的问题仍然存在,但我感谢您帮助整理我的代码:)
if __name__ == "__main__":
root = tk.Tk()
x = Windows(root)
x.start()
x.join()
root.mainloop()
I was using subprocess.run
instead of subprocess.Popen
, subprocess.run
waits for the terminal command to complete before moving on with the script.我使用的是
subprocess.run
而不是subprocess.Popen
, subprocess.run
在继续执行脚本之前等待终端命令完成。 Whereas subprocess.Popen
doesn't.而
subprocess.Popen
没有。
Edit: What I find strange is that when I would run it as a .py file subprocess.run
worked the same as subprocess.Popen
however when I had used pyinstaller then subprocess.run
worked how it's supposed to.编辑:我觉得奇怪的是,当我将运行它作为一个.py文件
subprocess.run
工作一样subprocess.Popen
然而,当我用了pyinstaller然后subprocess.run
工作它应该如何。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.