tkinter - 显示帧后运行功能 [英] tkinter - Run Function after Frame is Displayed

查看:29
本文介绍了tkinter - 显示帧后运行功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码在 OtherPage 类中有一个 onShowFrame 函数,该函数在显示 OtherPage 框架时运行.我的问题是 onShowFrame 函数中的所有内容都在框架实际显示给用户之前运行.我已经用 time.sleep(5) 证明了这一点.发生的情况是程序在显示 OtherPage 框架之前休眠 5 秒钟,停留在 BlankPage 上.我希望首先显示 OtherPage 框架,然后运行 ​​onShowFrame 函数中的任何内容.

The code below has an onShowFrame function in the OtherPage class that runs when the OtherPage frame is shown. My problem is that everything in the onShowFrame function runs before the frame is actually displayed to the user. I've demonstrated this with time.sleep(5). What happens is the program sleeps for 5 seconds, remaining on BlankPage, before showing the OtherPage frame. I want the OtherPage frame to be shown first and then anything in the onShowFrame function to run.

我该怎么做?

import tkinter as tk
import time

class Program(tk.Tk):        
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.iconbitmap(self, default = "")
        tk.Tk.wm_title(self, "")

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (BlankPage, OtherPage):

            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row = 0, column = 0, sticky = "nsew")

        self.showFrame(BlankPage)

    def showFrame(self,cont):
        frame = self.frames[cont]
        frame.tkraise()
        frame.event_generate("<<ShowFrame>>")

###########################################################################################################
class OtherPage(tk.Frame):
    def __init__(self, parent, controller):

        self.controller = controller
        tk.Frame.__init__(self, parent)

        innerFrame = tk.Frame(self)
        innerFrame.place(relx=.5, rely=.5, anchor="c", relwidth=1.0, relheight=1.0)

        innerFrame.grid_rowconfigure(0, weight=1)
        innerFrame.grid_columnconfigure(0, weight=1)

        self.frameOne = tk.Frame(innerFrame)
        self.frameOne.grid()

        label = tk.Label(self.frameOne, text = "Other Page")
        label.pack()

        self.bind("<<ShowFrame>>", self.onShowFrame)

    def onShowFrame(self, event):
        time.sleep(5)

###########################################################################################################

class BlankPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        innerFrame = tk.Frame(self)
        innerFrame.place(relx=.5, rely=.5, anchor="c", relwidth=1.0, relheight=1.0)

        innerFrame.grid_rowconfigure(0, weight=1)
        innerFrame.grid_columnconfigure(0, weight=1)

        self.frameOne = tk.Frame(innerFrame)
        self.frameOne.grid()

        button = tk.Button(self.frameOne, text = "Press", command = lambda: controller.showFrame(OtherPage))
        button.pack()

app = Program()
app.state('zoomed')
app.mainloop()

推荐答案

问题与您调用 sleep 导致应用程序休眠有关.为了更新显示,事件循环必须能够处理事件,而这在睡眠时是无法处理的.睡眠字面意思是停止所有处理.time.sleep 文档的前六个字是暂停当前线程的执行.

The problem is related to the fact that you're calling sleep which causes the application to sleep. In order for the display to update, the event loop has to be able to process events, which it cannot do while sleeping. To sleep literally means to stop all processing. The first six words of the documentation for time.sleep is Suspend execution of the current thread.

这是一个在小部件上调用 update 是合理的做法的地方.它将让 tkinter 有机会处理所有待处理的事件——例如完成处理按钮点击、重新绘制窗口等——在生成新事件之前.

This is one place where calling update on a widget is a reasonable thing to do. It will give tkinter a chance to process all pending events -- such as the finishing of handling a button click, redrawing the window, etc -- before generating the new event.

就像将您的函数更改为如下所示一样简单:

It's as easy as changing your function to look like this:

def showFrame(self,cont):
    frame = self.frames[cont]
    frame.tkraise()
    frame.update()
    frame.event_generate("<<ShowFrame>>")

这篇关于tkinter - 显示帧后运行功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆