我有一个简单的GUI,当按下按钮时,会使用Toplevel()显示一个子窗口。问题是直到该方法中的其余代码运行后才显示。我希望它先显示,然后转到下一行代码并继续。这是程序:
import os
import winreg
import tkinter
from tkinter import ttk
import ctypes
import sys
class MainWindow(ttk.Frame):
def __init__(self, parent):
ttk.Frame.__init__(self)
ttk.Frame.grid(self, column=0, row=0, sticky=('N', 'E', 'S', 'W'))
ttk.Frame.columnconfigure(self, 0, weight=1)
ttk.Frame.rowconfigure(self, 0, weight=1)
self.mem_exists = tkinter.StringVar()
self.reg_scan = tkinter.StringVar()
self.widgets()
def widgets(self):
self.mem_labl1 = ttk.Label(self, text='Memory Dumps:')
self.mem_labl1.grid(column=0, row=0)
self.mem_labl2 = ttk.Label(self, textvariable=self.mem_exists)
self.mem_labl2.grid(column=0, row=1)
self.mem_buton = ttk.Button(self, text='Delete', command=self.delete_dmps)
self.mem_buton.grid(column=0, row=2)
self.dmp_separ = ttk.Separator(self, orient='horizontal')
self.dmp_separ.grid(column=0, row=3, rowspan=1, sticky=('EW'))
self.scn_labl1 = ttk.Label(self, text='Scan for Dumps')
self.scn_labl1.grid(column=0, row=4)
self.scn_buton = ttk.Button(self, text='Scan', command=self.scan_pressed)
self.scn_buton.grid(column=0, row=5)
self.vrt_separ = ttk.Separator(self, orient='vertical')
self.vrt_separ.grid(column=1, row=0, rowspan=6, sticky=('NS'))
self.reg_labl1 = ttk.Label(self, text='Unneeded Keys')
self.reg_labl1.grid(column=2, row=0)
self.reg_labl2 = ttk.Label(self, textvariable=self.reg_scan)
self.reg_labl2.grid(column=2, row=1)
self.reg_buton = ttk.Button(self, text='Delete', command=self.delete_keys)
self.reg_buton.grid(column=2, row=2)
def scan_dumps(self):
'''Walks the OS drive and returns a dict with the path to and
size of each .DMP file found on the drive.'''
dumps = {}
k = 0
for dpath, dname, fname in os.walk('C:\\'):
for f_n in fname:
if f_n.endswith('.dmp'):
dumps[k] = [os.path.join(dpath, f_n), os.stat(os.path.join(dpath, f_n)).st_size]
k += 1
return dumps
def write_dumps(self):
dumps = self.scan_dumps()
with open(os.path.join(sys.path[0], 'practice_gui_2.ini'), 'w') as f:
for key, value in dumps.items():
f.write(f'{value}\n')
def read_dumps(self):
dumps = {}
k = 0
with open(os.path.join(sys.path[0], 'practice_gui_2.ini'), 'r') as f:
for line in f:
lst = line.split(',')
pth = lst[0][2:-1]
sze = lst[1][1:-2]
dumps[k] = [os.path.normpath(pth), sze]
k += 1
return dumps
def get_size(self):
'''Reads from ini created by "write_dumps()" and gets total size
of all .DMP files to display in the GUI.'''
dumps = self.read_dumps()
tsize = 0
for key, value in dumps.items():
tsize += int(value[1])
tsize /= 1024
tsize = round(tsize)
return format(tsize, ',')
def scan_pressed(self):
self.sub_win = tkinter.Toplevel(self)
self.write_dumps()
size = self.get_size()
self.mem_exists.set(f'{size} KB of memory dumps found!')
def get_profile_keys(self):
'''Opens a specific registry key and creates a list of key +
sub-key.'''
reg_key = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkList\\Profiles'
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, reg_key, 0, winreg.KEY_ALL_ACCESS | winreg.KEY_WOW64_64KEY) as k:
ns = winreg.QueryInfoKey(k)[0]
subs = []
for i in range(ns):
subs.append(reg_key + '\\' + winreg.EnumKey(k, i))
return subs
def get_newest_keys(self):
'''Takes "get_profile_keys" and decodes the "DateCreated" registry
value. Next finds the newest values per "DateCreated"and returns
a list of the full registry key for the newest key(s).'''
keys = self.get_profile_keys()
stamp = []
stamps = {}
for i in range(len(keys)):
reg_key = keys[i]
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, reg_key, 0, winreg.KEY_ALL_ACCESS) as k:
val = winreg.QueryValueEx(k, 'DateCreated')
stamp.append(int.from_bytes(val[0][:2], 'little'))
stamp.append(int.from_bytes(val[0][2:4], 'little'))
stamp.append(int.from_bytes(val[0][6:8], 'little'))
stamp.append(int.from_bytes(val[0][8:10], 'little'))
stamp.append(int.from_bytes(val[0][10:12], 'little'))
stamp.append(int.from_bytes(val[0][12:14], 'little'))
stamps[i] = stamp
stamp = []
if len(stamps) == 1:
return None
elif len(stamps) == 2:
z = 0
for x in stamps[0]:
if x > stamps[1][z]:
return keys[0]
elif x < stamps[1][z]:
return keys[1]
z += 1
# add condition for more than two keys
def delete_dmps(self):
'''Walks the dict created by "scan_dumps()"and removes each file
stored.'''
dumps = self.read_dumps()
for key, value in dumps.items():
path = value[0]
os.remove(path)
self.write_dumps()
size = self.get_size()
self.mem_exists.set(f'{size} KB of memory dumps found!')
def delete_keys(self):
'''Takes the list returned by "get_newest_keys" and deletes each
key.'''
delete = self.get_newest_keys()
if delete is None:
return None
elif isinstance(delete, str):
winreg.DeleteKey(winreg.HKEY_LOCAL_MACHINE, delete)
else:
for x in delete:
winreg.DeleteKey(winreg.HKEY_LOCAL_MACHINE, x)
def set_mem_label(self):
size = self.get_size()
self.mem_exists.set(f'{size} KB of memory dumps found!')
def set_reg_label(self):
keys = self.get_profile_keys()
if len(keys) > 1:
num = len(keys) - 1
self.reg_scan.set(f'{num} unwanted key(s) found!')
else:
self.reg_scan.set('No unwanted keys found!')
if ctypes.windll.shell32.IsUserAnAdmin():
root = tkinter.Tk()
gui = MainWindow(root)
gui.set_mem_label()
gui.set_reg_label()
gui.mainloop()
else:
ctypes.windll.shell32.ShellExecuteW(None, 'runas', sys.executable, 'practice_gui_2.py', None, 1)
此方法...:
def scan_pressed(self):
self.sub_win = tkinter.Toplevel(self)
self.write_dumps()
size = self.get_size()
self.mem_exists.set(f'{size} KB of memory dumps found!')
想要在显示窗口之前运行其余代码。我该如何解决?