更新了Tk,打破了.destroy

时间:2015-12-30 18:41:12

标签: python macos python-3.x tkinter tk

过去一年左右我一直在使用tkinter(来自python 3.2和3.4),并且从未遇到过小部件毁坏的问题。

我最近更新了我的Tk / Tcl版本(到ActiveTcl 8.5.18)并且还更新了我的操作系统(到MacOS 10.11)。起初似乎没有窗户会破坏,但我发现如果一个进程仍然在运行,那么destroy就会冻结窗口。

以下代码显示此问题:

#! usr/local/bin/python3.4

class kill_test:
    def __init__(self,r=None):
        import tkinter as tk
        if r is None:
            r=tk.Tk()
        self.r=r
        self.forever_flag=False
        self.withdraw=False
        self.buttons=[
            tk.Label(r,text='Set Hold Flag',relief='groove'),
            tk.Label(r,text='Destroy Root',relief='groove'),
            tk.Label(r,text='Withdraw and Destroy',relief='groove'),
            tk.Label(r,text='Destroy Self',relief='groove'),
            tk.Label(r,text='Quit Root',relief='groove'),
            tk.Label(r,text='Withdraw and Quit',relief='groove'),
            tk.Label(r,text='Make Toplevel',relief='groove')
            ]
        def r_destroy(s=self):
            print('root.destroy called')
            s.r.destroy()
        def b_destroy(s=self):
            print('button.destroy called')
            for b in self.buttons:
                if 'Self' in b['text']:
                    b.destroy()
        def r_quit(s=self):
            print('root.quit called')
            self.r.quit()
        def f_flag(s=self):
            print('changing loop_flag')
            self.forever_flag=(not self.forever_flag)
            for b in self.buttons:
                if 'Flag' in b['text']:
                    if self.forever_flag:
                        b.base_fg='red'
                    else:
                        b.base_fg='black'
        def w_destroy(s=self):
            print('withdrawing and destroying')
            self.r.withdraw()
            self.r.destroy()
        def w_quit(s=self):
            print('withdrawing and quitting')
            self.r.withdraw()
            self.r.quit()
        def t_cmd(s=self):
            T=tk.Toplevel()
            kill_test(T)
        self.cmds=[
            f_flag,
            r_destroy,
            w_destroy,
            b_destroy,
            r_quit,
            w_quit,
            t_cmd
            ]
        i=0;j=0
        for b,cmd in zip(self.buttons[:-1],self.cmds[:-1]):
            b.base_fg=b['fg']
            b.bind('<Enter>',lambda e:e.widget.config(bg='lightblue',fg='white'))
            b.bind('<Button-1>',lambda e:e.widget.config(bg='darkblue'))
            b.bind('<ButtonRelease-1>',lambda e,c=cmd:(e.widget.config(bg='lightblue'),c()))
            b.bind('<Leave>',lambda e:e.widget.config(bg='white',fg=e.widget.base_fg))
            b.grid(row=i,column=j,sticky='ew')
            i+=1
            if i>2:
                i=0
                j+=1
        b=self.buttons[-1];cmd=self.cmds[-1]
        b.base_fg=b['fg']
        b.bind('<Enter>',lambda e:e.widget.config(bg='lightblue',fg='white'))
        b.bind('<Button-1>',lambda e:e.widget.config(bg='darkblue'))
        b.bind('<ButtonRelease-1>',lambda e,c=cmd:(e.widget.config(bg='lightblue'),c()))
        b.bind('<Leave>',lambda e:e.widget.config(bg='white',fg=e.widget.base_fg))
        b.grid(row=3,column=0,columnspan=2,sticky='ew')

    def run(self):
        self.r.mainloop()

if __name__=='__main__':
    import time
    t=kill_test()
    t.run()
    if t.forever_flag:
        time.sleep(10)

从命令行调用,如果没有按“设置保持标记”按钮,则一切都会顺利退出。

另一方面,如果有人按下它,那么试图通过任何机制破坏窗口只是将窗口冻结到位,直到time.sleep退出。

过去,窗户至少会先消失。

如果有人调用'提取和销毁'按钮,则窗口仍然可见但不活动。如果一个人调用“提取和退出”按钮,它就会消失。

最后,顶层窗口会破坏很好(正如预期的那样,考虑到从未调用过循环),无论对它们做了什么。我放入了测试的顶级按钮版本。

有没有人有关于如何恢复旧行为的提示?

0 个答案:

没有答案