这个tkinter程序怎么了?

时间:2018-12-14 06:20:36

标签: python python-3.x tkinter

import random
import time
from tkinter import *    

root = Tk()

x = ""

lab = Label(root,text = x)
lab.pack()

root.mainloop()

def randomno():
    while (1):
        y = random.randint(1, 100)
        y = StringVar()
        x = y.get()
        lab["text"] = x
        #root.update_idletasks()
        time.sleep(2)

randomno()

错误:

Traceback (most recent call last):   File
   "C:/Users/Acer/PycharmProjects/unseen/tp.py", line 26, in <module>
       randomno()   File "C:/Users/Acer/PycharmProjects/unseen/tp.py", line 20, in randomno
       y = StringVar()   File "C:\Users\Acer\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py",
   line 480, in __init__
       Variable.__init__(self, master, value, name)   File "C:\Users\Acer\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py",
   line 317, in __init__
       self._root = master._root() AttributeError: 'NoneType' object has no attribute '_root'

2 个答案:

答案 0 :(得分:0)

这是因为您的代码意图是错误的。我建议您使用类结构来组织程序。此外,您的无限循环会阻塞tkinter主循环,因此即使您修复了代码,窗口也会冻结。 所以这是工作示例:

import random
import time
from threading import Thread
from tkinter import *


class stack_overflow():
  def __init__(self, master):
      self.master = master
      self.x = 'trial'

      self.lab = Label(self.master, text=self.x)
      self.lab.pack(side="left")
      self.start_radome()

  def start_radome(self):
      radome_thread = Thread(target=self.randomno)
      radome_thread.start()

  def randomno(self):
      while True:
          self.x = random.randint(1, 100)
          self.lab.config(text='%s' % self.x)
          time.sleep(1)

if __name__ == '__main__':
      root = Tk()
      app = stack_overflow(master=root)
      root.mainloop()

所以您开始tkinter,这是您的主线程。在另一个线程中启动无限循环。因此,您的tkinter窗口将不会冻结。

答案 1 :(得分:0)

这是在tkinter中执行所需操作的常用方法:

import random
import time
import tkinter as tk

DELAY = 2000  # milliseconds (thousandth of a second)

def randomno():
    x = random.randint(1, 100)
    lab["text"] = x
    #time.sleep(2)  # Don't call this in a tkinter program!
    root.after(DELAY, randomno)  # Call this function again after DELAY ms.


root = tk.Tk()

lab = tk.Label(root, text="")
lab.pack()

randomno()  # Starts periodic calling of itself.
root.mainloop()

您无需使用StringVar,只需在randomno()函数中分配新的随机值即可。

您不应该在time.sleep()应用程序中调用tkinter。请改用通用窗口小部件方法after()。请注意上面的代码中randomno()如何调用root.after()来安排自己稍后被再次调用。

这就是在tkinter程序中定期执行某项操作的方法,并且这种方法将在调用sleep()时保持GUI不会“挂起”。