Python Tkinter在使用pyinstaller后更新标签

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

当我运行.py文件时,程序运行正常,就像在运行robocopy时的self.error更新一样。但是,在我使用
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()