为什么我的 Tkinter 窗口有时根本不显示? [英] Why does my Tkinter window sometimes not display at all?

查看:111
本文介绍了为什么我的 Tkinter 窗口有时根本不显示?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Tkinter 窗口大部分时间都能正确显示,但有时随机不显示.这是一个重大的痛苦.我已经尝试了各种方法(例如在 Tkinter 窗口构建过程中省略了任何 Pygame 渲染),并且我已经确认窗口坐标在显示或不显示时完全相同.我试过 lift 窗口,我试过 force_focus 在窗口上,但没有任何效果.

My Tkinter window displays correctly most of the time, but then sometimes, randomly, doesn't display. It's a major pain. I've tried various things (such as leaving out any Pygame rendering during the Tkinter window construction) and I've confirmed the window coordinates are exactly the same when displayed, or not displayed. I've tried to lift the window, I've tried to force_focus on the window, but nothing is working.

这是我的代码:

# 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 的错误?请问有人知道是怎么回事吗?

As the window is displaying about half of the time, I consider my code to be fine, and this is possibly a fault with either Tkinter or even Windows? Does anybody know what is happening please?

这是对 first_time_setup 的调用:

if first_time:
    first_time_setup()

first_time = False

所以任何进一步的调用都会触发函数内的 else 语句.

So any further calls will trigger the else statement within the function.

推荐答案

最近很多人都在问这类问题,其中涉及到 overrideredirect.所以这里有一个更长的回应,关于它为什么发生以及(在这种情况下)你如何可能修复它.一旦执行了 master.overrideredirect(1) 行,窗口管理器就不会向窗口发送焦点或其他事件消息.可能解决您的问题的是在初始化结束时执行 master.overrideredirect(1) .另请注意,一旦您执行该命令,窗口管理器基本上会忽略该窗口.分别用 master.overrideredirect(1)master.overrideredirect(0) 试试这个实验.渲染窗口后,使用 键在窗口之间循环.注意,当master.overrideredirect(1)时,窗口不会出现在窗口列表中循环.最后,如果用户 离开窗口,则没有事件发送到应用程序来检测这一点,并且用户可能很难设置焦点回到窗口,这取决于它们覆盖了多少个重叠窗口.

A lot of people have been asking this type of question lately where overrideredirect is involved. So here is a little longer response as to why it happens and (in this case) how you can potentially fix it. Once you execute the line master.overrideredirect(1), window managers don't send focus or other event messages to the window. What might solve your problem is to do master.overrideredirect(1) at the very end of your initialization. Note also, that once you execute the command, the window manager essentially ignores the window. Try this experiment with master.overrideredirect(1) and master.overrideredirect(0) separately. Once the window is rendered, use the <Alt-Tab> keys to cycle through the windows. Notice that when master.overrideredirect(1), the window does not show up in the window list to cycle through. Finally, if the user does <Alt-Tab> away from the window, there is no event sent to the application to detect this, and the user may have a very difficult time setting focus back on the window, depending on how many overlapping windows they have covering it.

通常情况下,由于缺乏用户控制,拥有无边框主窗口是不明智的.overrideredirect 存在的原因可能是为了能够创建自定义临时实用程序和像组合框之类的超级小工具.

Typically, it is unwise to have a borderless main window due to lack of user control of it. The reason overrideredirect exists is probably for enabling the creation of custom temporary utility and megawidgets like comboboxes and such.

这篇关于为什么我的 Tkinter 窗口有时根本不显示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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