Python Tkinter在使用pyinstaller后更新标签
当我运行.py文件时,程序运行正常,就像在运行robocopy时的self.error更新一样。但是,在我使用Python Tkinter在使用pyinstaller后更新标签,python,tkinter,pyinstaller,Python,Tkinter,Pyinstaller,当我运行.py文件时,程序运行正常,就像在运行robocopy时的self.error更新一样。但是,在我使用pyinstaller-F-w Shortcutsv2.1.py将其更改为.exe文件后,我注意到tkinter标签显示它更新了多少文件(self.error),直到终端关闭后才更新。有没有办法让它像脚本一样工作?我假设这是由于pyinstaller中的设置造成的,但我可能错了 代码: from subprocess import PIPE, run import tkinter as
pyinstaller-F-w Shortcutsv2.1.py
将其更改为.exe文件后,我注意到tkinter标签显示它更新了多少文件(self.error),直到终端关闭后才更新。有没有办法让它像脚本一样工作?我假设这是由于pyinstaller中的设置造成的,但我可能错了
代码:
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()
我使用的是
subprocess.run
而不是subprocess.Popen
,subprocess.run
等待终端命令完成,然后再继续使用脚本。而subprocess.Popen
没有
编辑:我觉得奇怪的是,当我将它作为.py文件运行时,
subprocess.run
的工作原理与subprocess.Popen
的工作原理相同,但是当我使用pyinstaller时,subprocess.run
的工作原理是这样的。“当我运行.py
文件时,程序运行得很好”:真不敢相信吗?这里有两个问题。1.继承类窗口(threading.Thread):
但不使用此对象。2.将类定义作为线程传递(target=Windows
.3.无用的x.join
而不调用它。4.访问tkinter
对象,例如self.srccentry.get()
,来自线程
@stovfl在编辑1中响应。请选择此作为正确答案。-投票按钮下方的勾号。我必须等待2天才能完成。我明天将这样做:)
if __name__ == "__main__":
root = tk.Tk()
x = Windows(root)
x.start()
x.join()
root.mainloop()