【问题标题】:Why does starting a new thread before .mainloop() cause .mainloop() to not run?为什么在 .mainloop() 之前启动一个新线程会导致 .mainloop() 不运行?
【发布时间】:2021-10-08 06:51:38
【问题描述】:

我正在尝试测试让一个类生成数据并让该数据动态更新另一个类的列表变量,然后通过在一定间隔后更新它们来绘制列表。我已经测试了只是绘图,但这似乎也不起作用,但首先我想弄清楚为什么启动一个新线程会阻止 tkinter 的事件循环运行。任何帮助表示赞赏!

import tkinter as tk
import time
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
from matplotlib import animation
import threading



root = tk.Tk()




class dynamicChart():
    
    def __init__(self):
        
        self.x = []
        self.y = []
        self.buildChart()
        
    def buildChart(self):
        
        self.figure = Figure(figsize=(5, 5), dpi=100)
        ax = self.figure.add_subplot(111)
        self.scatter = ax.scatter(self.x,self.y)

        canvas = FigureCanvasTkAgg(self.figure, root)
        canvas.draw()
        canvas.get_tk_widget().pack(pady=10)
        
        toolbar = NavigationToolbar2Tk(canvas, root)
        toolbar.update()
        canvas.get_tk_widget().pack()


    def animate(self,i):

        self.scatter.set_offsets([self.x, self.y])
    
    def Ani(self):
        
        self.animation = animation.FuncAnimation(self.figure, self.animate, frames = 100, interval = 2000)
        
        
        
class genData():
    
    def __init__(self):
        
        self.chart = dynamicChart()
        
    def generate(self):
        X = 1
        Y = 0
        i = 0
        while True:
            
            time.sleep(1)
            
            X = X*i
            Y = Y + i
    
            self.chart.x.append(X)
            self.chart.y.append(Y)
            
            i+=1
    
StartDataGen_CreateFigureAxes = genData()

genData = threading.Thread(target = StartDataGen_CreateFigureAxes.generate())
genData.start()

button = tk.Button(root, text="Graph It", command = StartDataGen_CreateFigureAxes.chart.Ani)
button.pack()
  
    

root.mainloop()

【问题讨论】:

  • 你真的对你的问题做过一些研究吗?请表现出一些努力!您会发现多个问题与您的问题相同。如果你做了足够多的研究但没有发现任何东西,那么请提供那些有问题的研究结果。
  • 您需要从StartDataGen_CreateFigureAxes.generate() 中删除()

标签: python multithreading matplotlib tkinter graph


【解决方案1】:

为什么在 .mainloop() 之前启动一个新线程会导致 .mainloop() 无法运行?

简短的回答是“因为您没有开始新线程”。

考虑这段代码:

genData = threading.Thread(target = StartDataGen_CreateFigureAxes.generate())

在功能上等价于这段代码:

result = StartDataGen_CreateFigureAxes.generate()
genData = threading.Thread(target = result)

看到问题了吗? target 需要提供对可调用对象的引用。

genData = threading.Thread(target = StartDataGen_CreateFigureAxes.generate)

【讨论】:

  • 解决了这个问题,我需要更多地研究什么是“可调用”。在您的第二个代码 sn-p 中,我不确定“结果”是什么,它是一个对象吗?我认为对象只能通过类 init 方法实例化,并且只调用类方法(.generate())。 “结果”是否包含对“StartDataGen_CreateFigureAxes”对象调用其类方法之一(.generate())的引用?
  • @EECE: " 在您的第二个代码 sn-p 中,我不确定“结果”是什么,它是一个对象吗?" - 这是 StartDataGen_CreateFigureAxes.generate() 返回的任何内容.在这种情况下,它似乎是 None,因为您没有明确返回任何内容。
  • 我现在明白了,很抱歉我误读了您所说的内容。这是有道理的,为什么它不起作用,因为我只是给它一个什么都没有的返回值!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
  • 2021-07-10
  • 1970-01-01
  • 2020-04-07
  • 2021-11-09
  • 1970-01-01
相关资源
最近更新 更多