【发布时间】:2014-03-20 21:18:30
【问题描述】:
我将 tk 用于项目的 GUI。我有一些非常奇怪的行为,但仅作为 Windows 上的内置可执行文件。本质上,我有一个函数启动一个新进程,并在完成后需要更新一些 GUI 元素。这在运行解释的 OS X 和 Windows 上运行良好。它可以作为 OS X 二进制文件正常工作。但作为 Windows 二进制文件,该代码会导致出现第二个主窗口,原因不明。
应用通过以下方式启动:
root = tk.Tk()
root.withdraw()
app = impy()
root.mainloop()
在哪里
class impy(tk.Toplevel):
然后某个时候,用户单击了一个按钮,导致它运行:
dialog = Progress_Dialog()
dialog.set_text('Implosion generation...')
dialog.update_idletasks()
# Use helper function:
parent_conn, child_conn = Pipe()
p = Process(target=ImplosionRunner.run, args=(child_conn,))
self.processes.append(p)
# start the process and send implosion:
p.start()
try:
parent_conn.send(self.imp)
except:
raise Exception('Implosion object passed to ImplosionRunner is not pickleable!')
obj = None
# Loop while the process is active:
def callback():
nonlocal dialog, p, parent_conn
if dialog.cancelled:
dialog.withdraw()
p.terminate()
return
# Try to receive from the Pipe:
if parent_conn.poll():
# Update the progress, or end otherwise:
obj = parent_conn.recv()
if isinstance(obj, Exception):
from tkinter.messagebox import showerror
showerror('Error!', 'A problem occurred generating the implosion (class '+self.imp.name()+')\n'+obj.__str__())
dialog.withdraw()
p.terminate()
return
elif isinstance(obj, float):
dialog.set(100*obj)
elif isinstance(obj, Implosion):
# Pass info back to the main app:
self.imp = obj
self.after(10, self.__postImplosion__)
dialog.withdraw()
p.terminate()
return
self.after(25, callback)
self.after(10, callback)
回调循环最终通过elif isinstance(obj, Implosion) 子句完成。然后这些函数都被调用。他们所做的事情会导致出现第二个顶级窗口,该窗口本质上是主窗口的克隆。 UI 操作应用于克隆。 __postImplosion__ 方法只是:
for key in self.modControlChecks.keys():
self.modControlChecks[key].configure(state=tk.NORMAL)
# Run any modules that were already checked in refresh mode
for key in self.modControlChecks.keys():
self.modRedisplay[key] = (self.modControlVars[key].get() == 1)
for mod in allModules():
if self.modRedisplay[mod.name()]:
self.__runModule__(mod.name())
它只需要遍历一些复选框并启用它们。我很困惑,因为这只是 Windows 二进制文件的问题。有什么想法吗?
更新:更多疑难解答:在调用p.start() 后立即出现额外的主窗口。所以这似乎是一些奇怪的行为。为什么我不能在没有出现额外 Tk 窗口的情况下启动进程?
【问题讨论】: