0

我正在编写一个“向导”类型的 Python Tkinter GUI,它从用户那里收集信息,然后根据用户的条目执行几个操作:文件复制、数据库更新等。处理通常需要 30-60 秒,在此期间,我想要:

  1. 向用户提供有关活动和进度的文本更新
  2. 阻止用户关闭应用程序,直到它完成它正在做的事情

我开始着手让文本更新出现在一个子窗口中,该子窗口被配置为trainsientwait_window用于暂停主循环,直到活动完成。这对于我创建的具有调用窗口方法的确定/取消按钮的其他自定义对话框来说效果很好destroy。基本方法是:

def myCustomDialog(parent,*args):
    winCDLG = _cdlgWin(parent,*args)
    winCDLG.showWin()
    winCDLG.dlgWin.focus_set()
    winCDLG.dlgWin.grab_set()
    winCDLG.dlgWin.transient(parent)
    winCDLG.dlgWin.wait_window(winCDLG.dlgWin)
    return winCDLG.userResponse

class _cdlgWin():
    def __init__(self,parent,*args):
        self.parent = parent
        self.dlgWin = tk.Toplevel()
        self.userResponse = ''

    def showWin(self):
        #Tkinter widgets and geometry defined here

    def _btnOKClick(self):
        #self.userResponse assigned from user entry/entries on dialog
        self.dlgWin.destroy()

    def _btnCancelClick(self):
        self.dlgWin.destroy()

但是,这种方法不适用于我要创建的新监视和更新对话框。

首先,因为没有用户启动的操作来触发复制/更新活动,然后是destroy,我必须将它们放在 showWin 或其他方法中。我已经尝试了两种方法,但我陷入了竞争条件(代码完成了复制/更新内容,但随后尝试在窗口存在之前销毁窗口),并且从不首先执行复制/更新内容,因为它wait_window在我可以激活其他方法之前点击。

如果我能找到解决办法,那么下面的答案将涵盖次要问题(防止用户在工作完成之前关闭子窗口)。

那么......有没有什么我可以申请的创可贴来使这种方法按我想要的方式工作?还是我需要废弃它,因为它不起作用?(如果是后者,有什么办法可以实现最初的目标吗?)

4

2 回答 2

7

self.dlgWin.overrideredirect(1)将删除所有按钮(制作无边框窗口)。那是你要找的吗?

于 2013-06-17T22:00:46.630 回答
3

据我所知,窗口控制按钮是由窗口管理器实现的,所以我认为不可能只用 Tkinter 删除其中一个(虽然我不是 100% 确定)。这个问题的常见解决方案是为协议设置一个回调WM_DELETE_WINDOW并使用它来控制窗口的行为:

class _cdlgWin():
    def __init__(self,parent,*args):
        self.parent = parent
        self.dlgWin = tk.Toplevel()
        self.dlgWin.protocol('WM_DELETE_WINDOW', self.close)
        self.userResponse = ''

    def close(self):
        tkMessageBox.showwarning('Warning!',
                                 'The pending action has not finished yet')
    # ...
于 2013-06-15T11:30:11.030 回答