LINUX.ORG.RU

Понимание потоков в python/tkinter и matplotlib. Объясните пожалуйста где ошибка?

 , , , ,


0

2

Если код вставить и запустить, он будет работать, но заблокирет окошкко от перемещения:

Вопрос как поправить и где чтобы потоки работали как надо, графики рисовали, а окошко не блокировалось?

import random
import threading
import time
import tkinter as tk
from queue import Empty, Queue
from time import time as timer
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg


def get_xy_from_db(id):  # generate dummy data
    #time.sleep(random.random())  # emulate blocking function
    list_x = list(range(1, 16))
    list_y = list(random.sample(range(0,100),15))
    res_lst = list_x + list_y
    return res_lst


def poll_db(id, emit):  # NOTE: interval is independant from the delay
    while True:
        #time.sleep(interval)
        emit(get_xy_from_db(id))


def poll_db_2(id, emit):  # NOTE: interval is independant from the delay
    while True:
        #time.sleep(interval)
        emit(get_xy_from_db(id))


def make_x_y(list_a):    
    done_x=list_a[:15]
    done_y=list_a[15:]    
    return done_x, done_y    


def start_polling_loop(root, q, delay):
    def loop():
        timeout_millis = round(delay - (1000 * timer()) % delay)
        root.after(timeout_millis, loop)
        a.clear()
        try:
            data = q.get(block=False)
            x, y = make_x_y(data)
            a.plot(x, y)
            canvas.draw()
        except Empty:
            return

    root.after_idle(loop)  # start


def start_polling_loop_2(root, q_2, delay):
    def loop():
        timeout_millis = round(delay - (1000 * timer()) % delay)
        root.after(timeout_millis, loop)
        a1.clear()
        try:
            data = q_2.get(block=False)
            x, y = make_x_y(data)
            a1.plot(x, y)
            canvas.draw()
        except Empty:
            return

    root.after_idle(loop)  # start

if __name__ == "__main__":
    root = tk.Tk()
    q = Queue()  # первая очередь для первого графика
    q_2 = Queue()  # вторая очередь для второго

    # соответствующие потоки
    threading.Thread(target=poll_db, args=[1, q.put], daemon=True).start()
    threading.Thread(target=poll_db_2, args=[2, q_2.put], daemon=True).start()

    start_polling_loop(root, q, delay=40)
    start_polling_loop_2(root, q_2, delay=40)

    f = Figure(figsize=(8, 4), dpi=100)

    a = f.add_subplot(1, 2, 1)  # расширим сетку для второго графика
    a1 = f.add_subplot(1, 2, 2)  # добавим второй график в сетку

    canvas = FigureCanvasTkAgg(f, master=root)
    canvas.show()
    canvas.get_tk_widget().grid(row=0, column=0)

    root.mainloop()

★★★★★

Последнее исправление: sniper21 (всего исправлений: 2)

Люди, помогите пожалуйста что же не правильно работает?

Вроде цикл: пришли данные, в get их прочитали и пошли рисовать, если данных нет, то оставить нарисованное ранее. Цикл выполнять после отрисовки GUI.

sniper21 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.