为什么我的Tkinter窗口有时根本不显示?

时间:2017-07-02 10:02:59

标签: python tkinter

我的Tkinter窗口大部分时间都能正确显示,但有时会随机显示。这是一个很大的痛苦。我尝试了各种各样的东西(例如在Tkinter窗口构造期间省略任何Pygame渲染)并且我已经确认窗口坐标在显示时完全相同,或者没有显示。我试过lift窗口,我试图在窗口force_focus,但没有任何效果。

这是我的代码:

# Function to take a postcode and station using Tkinter:
def first_time_setup():
    global test_w, test_r, default_colour

    master = Tk()
    master.withdraw()

    master.overrideredirect(1)
    back_img = PhotoImage(file=find_data_file('Outlooker_background.png'))
    back_label = Label(master, image=back_img)
    back_label.place(x=0, y=0, relwidth=1, relheight=1)
    back_label.image = back_img

    text_font = font.Font(family='Arial', size=12)
    button_font = font.Font(family='Calibri Light', size=11, weight="bold")

    master.columnconfigure(0, weight=3)
    e_weather = Entry(master, font=text_font, width=15)
    e_weather.grid(row=0, column=1, padx=5, pady=(15, 5), sticky=E)
    b_weather = Button(master, text="TEST", font=button_font,
                       bg='light blue', command=lambda: test_weather(e_weather.get(), b_weather, b_done))
    b_weather.grid(row=0, column=2, padx=(0, 15), pady=(12, 0), sticky=E)

    e_rail = Entry(master, font=text_font, width=15)
    e_rail.grid(row=1, column=1, padx=5, pady=5, sticky=E)
    b_rail = Button(master, text="TEST", font=button_font,
                    bg='light blue', command=lambda: test_rail(e_rail.get(), b_rail, b_done))
    b_rail.grid(row=1, column=2, padx=(0, 15), sticky=E)

    b_done = Button(master, text="DONE", font=button_font, state=DISABLED,
                    bg='light blue', command=lambda: testing_done(master))
    b_done.grid(row=2, column=2, padx=(0, 15), pady=10, sticky=E)

    if first_time:
        b_quit = Button(master, text="QUIT", font=button_font,
                        bg='light blue', command=lambda: sys.exit(0))
    else:
        b_quit = Button(master, text="EXIT", font=button_font,
                        bg='light blue', command=lambda: master.destroy())
        pygame.draw.rect(screen, black, (223, 296, 417, 134))
        pygame.display.flip()

    b_quit.grid(row=2, padx=15, pady=10, sticky=W)
    default_colour = b_quit.cget("background")

    master.update_idletasks()  # Update "requested size" from geometry manager
    x = (master.winfo_screenwidth() - 417) / 2
    y = (master.winfo_screenheight() - 134) / 2
    master.geometry("417x134+%d+%d" % (x, y))
    master.deiconify()
    master.lift()
    master.focus_force()
    e_weather.focus_set()
    master.mainloop()

由于窗口显示大约一半的时间,我认为我的代码没问题,这可能是Tkinter甚至Windows的错误?有人知道发生了什么吗?

编辑:这是对first_time_setup的调用:

if first_time:
    first_time_setup()

first_time = False

因此,任何进一步的调用都会触发函数中的else语句。

1 个答案:

答案 0 :(得分:1)

很多人最近一直在问这类问题,其中涉及overrideredirect。所以这里有一个更长的响应,为什么它发生和(在这种情况下)你如何可能修复它。执行第master.overrideredirect(1)行后,窗口管理员不会将焦点或其他事件消息发送到窗口。可能解决您问题的方法是在初始化结束时执行master.overrideredirect(1)。另请注意,一旦执行该命令,窗口管理器实际上会忽略该窗口。分别使用master.overrideredirect(1)master.overrideredirect(0)尝试此实验。渲染窗口后,使用<Alt-Tab>键在窗口中循环。请注意,当master.overrideredirect(1)时,窗口列表中不会显示窗口以循环显示。最后,如果用户离开窗口<Alt-Tab>,则没有事件发送到应用程序以检测到这一点,并且用户可能很难将焦点设置回窗口 ,取决于他们覆盖它的重叠窗口数量。

通常,由于缺乏用户对它的控制,拥有无边框主窗口是不明智的。 overrideredirect存在的原因可能是为了创建自定义临时实用程序和megobidgets,例如组合框等。