【问题标题】:Tkinter window background color does not reflect in the windowTkinter 窗口背景颜色不反映在窗口中
【发布时间】:2022-11-17 00:39:01
【问题描述】:
import time
import tkinter
global win

def func1():
   global win
   win = tkinter.Tk()
   win.geometry("300x200")
   win.configure(bg='blue')
   time.sleep(5)
   button_win = tkinter.Button(win,text='Go',command=func2)
   button_win.pack()
   print('mainloop')
   win.mainloop()

def func2():
   print("func2")
   global win
   win.configure(bg = 'green')
   time.sleep(5)
   print("in func1")
   time.sleep(5)
   print("func3 call")
   func3()

def func3():
   global win
   time.sleep(5)
   win.configure(bg = 'yellow')

func1()

控制台中的输出

mainloop
(I click on 'Go' button)
func2
in func1
func3 call

我已经使用 time.sleep(5) 来查看更改是否反映在窗口中。 窗口以蓝色打开。单击“开始”按钮后,几秒钟后,它变为黄色。但是为什么当它进入函数'func2'时它没有变成绿色。我怎么做?

【问题讨论】:

  • 这回答了你的问题了吗? tkinter and time.sleep
  • 不,但感谢@Thingamabobs。我使用 time.sleep(5) 只是为了查看窗口是否变绿。否则这里不需要 time.sleep(5)。它可以从代码中删除。
  • 与问题无关,但切勿将 time.sleep() 与 tkinter 一起使用,请使用 tkinter .after() method
  • 谢谢@TrooperZ,我会记住这一点。
  • 我一直评论。睡眠(5),仍然窗口没有更新为绿色

标签: python user-interface tkinter


【解决方案1】:

基本上发生的事情是您不会返回到命令和所有其他花哨的东西发生/执行的地方mainloop。如果不处理例如win.configure(bg='green'),您的窗口将不会变绿。因此,在更改背景颜色的值之前,您应该确保update_idletasks() 或返回mainloop

另外在全局命名空间中使用 global 是没有意义的。只有当你想在全局命名空间中放置一个变量时才使用 global,你不需要它来访问全局命名空间,因为在模块中,所有内容都被路由到全局命名空间。

还要注意 time.sleep 停止 mainloop 睡眠秒数,你应该避免这种情况,出于同样的原因你的窗口不会变绿。主循环处理所有事件和内容,因此您的窗口将变得无响应。

一个工作代码示例是:

import time
import tkinter

def func1():
   global win
   win = tkinter.Tk()
   win.geometry("300x200")
   win.configure(bg='blue')
   button_win = tkinter.Button(win,text='Go',command=func2)
   button_win.pack()
   win.mainloop()

def func2():
   win.configure(bg = 'green')
   win.update_idletasks()
   time.sleep(5)
   func3()

def func3():
    win.configure(bg = 'yellow')
    win.update_idletasks()

func1() 

【讨论】:

  • 感谢@Thingamabobs 提出 update_idletasks() 函数的想法。这是一个巨大的帮助。
  • @Nupur 不客气,感觉像是似曾相识的感觉。你有没有考虑过接受这个答案或者你觉得它不值得?
【解决方案2】:

编辑:添加完整版本的代码

首先,正如 Trooper Z 提到的,如果您不使用线程,则在使用 tkinter 时应避免使用 time.sleep。 如果你不需要,你也应该避免使用全局变量。

首先,我删除了所有 time.sleeps,因为我们不需要。程序已经进入 mainloop 中的一个循环。我们还将 func2 连接到按钮。我们使用 lambda 能够将窗口作为参数发送。

def func1():
   win = tkinter.Tk()
   win.geometry("300x200")
   win.configure(bg='blue')
   button_win = tkinter.Button(win,text='Go',command=lambda:func2(win))
   button_win.pack()
   win.mainloop()

在 func2 中,我们将颜色更改为绿色,然后在方法之后使用。 之后做的是,等待第一个参数以毫秒为单位(在这种情况下为 5000 = 5 秒)而不是调用函数

def func2(win):
   win.configure(bg = 'green')
   win.after(5000,lambda:func3(win))

这是 func3

def func3(win):
   win.configure(bg = 'yellow')

完整版代码

import tkinter

def func1():
   win = tkinter.Tk()
   win.geometry("300x200")
   win.configure(bg='blue')
   button_win = tkinter.Button(win,text='Go',command=lambda:func2(win))
   button_win.pack()
   win.mainloop()

def func2(win):
   win.configure(bg = 'green')
   win.after(5000,lambda:func3(win))

def func3(win):
   win.configure(bg = 'yellow')

func1()

【讨论】:

  • FWIW,这里不需要lambda。你可以做win.after(5000, func3, win)
  • 感谢@BryanOakley 分享有关“使用后”的知识。
  • 感谢@Mustafa 给出“使用后”的想法。我运行了你写的内容,但屏幕并没有随时变为绿色。
  • 是的,但只是习惯于使用 lambda 作为命令参数,否则不支持参数。不管怎么说,还是要谢谢你。 @Nupur 我刚刚再次测试了代码,当我按下 Go 按钮时,它变成了绿色。 5 秒后变成黄色。我添加了完整版本的代码,你能再试一次吗?
猜你喜欢
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 2022-09-24
  • 1970-01-01
  • 1970-01-01
  • 2018-10-01
  • 2012-02-15
  • 1970-01-01
相关资源
最近更新 更多