Tkinter получает «основной поток не в основном цикле» тогда и только тогда, когда есть новый pyplot

#python #matplotlib #tkinter

#python #matplotlib #tkinter

Вопрос:

Я мог бы запустить threaded tkinkter без каких-либо проблем, если бы после этого я не выводил никаких новых фигур с помощью matplotlib.pyplot. Однако, когда я строю новую фигуру с помощью pyplot, я получу main thread is not in main loop for BooleanVar или любой другой tkinter var ( StringVar , IntVar ) . Я не мог разобраться в этом.

 import tkinter as tk
import threading
import matplotlib.pyplot as plt

class App(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.setDaemon(True)
        self.start()

    def run(self):
        self.root = tk.Tk()

        #Plotting this label has no issue at all
        l1= tk.Label(self.root, text="label 1", fg="white", bg='gray')
        l1.grid(column=0, row=r, columnspan=2)

        #The first line below is where issue lies
        c1v = tk.BooleanVar() 
        c1v.set(True)
        c1 = tk.Checkbutton(self.root, text='checkbox 1', var=c1v, command=self.callback, anchor="w")
        c1.grid(sticky="W", column=0, row=r)

        self.root.mainloop()
 

Проблема возникает, когда я делаю что-то подобное в моем main.py:

 app = App()

#Without this line below it runs perfectly fine
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(4, 4), subplot_kw=dict(polar=True))
 

В чем причина и как это исправить? Спасибо!

Комментарии:

1. tkinter и matplotlib есть известные проблемы с потоками . Это меня настигло и обошлось путем отправки информации обратно через глобальные переменные на график в основном потоке.

2. Это неожиданно и странно. Есть ли у PyQt такая проблема?

3. не уверен в PyQt извините. Прошел достаточно далеко по маршруту tk, чтобы повернуть назад! Вам нужно выполнять поток всей программы? Можете ли вы структурировать программу так, чтобы интерфейс / отображение осуществлялось через основной поток, а затем создавать потоки для вашей требуемой задачи? В моем случае я имел дело с воспроизведением звука, поэтому я потоковое воспроизведение, чтобы избежать зависания графического интерфейса во время воспроизведения звука, а затем отправил обратно позицию воспроизведения для обновления графика с помощью progressbar.