Обновление тепловой карты в ткинтере без закрытия окна - PullRequest
0 голосов
/ 03 сентября 2018

У меня проблемы с обновлением кадра в tkinter. Я должен закрыть окно, чтобы обновить мой кадр. Значение моего термодатчика меняется каждый раз. Я посмотрел root.after(), но не понял.

Как мне обойтись, не закрывая его?

Мой код здесь:

try:
    from tkinter import *
except ModuleNotFoundError:
    from tkinter import *  # Python 3




f = open('text.txt', 'r')
nodes_list = [[int(item) for item in line.split()] for line in f]
heat_map = nodes_list
heat_min = min(min(row) for row in heat_map)
heat_max = max(max(row) for row in heat_map)
print('hello')
palette = (0, 0, 1), (0, .5, 0), (0, 1, 0), (1, .5, 0), (1, 0, 0)


def pseudocolor(value, minval, maxval, palette):
    """ Maps given value to a linearly interpolated palette color. """
    max_index = len(palette)-1
    # Convert value in range minval...maxval to the range 0..max_index.
    v = (float(value-minval) / (maxval-minval)) * max_index
    i = int(v); f = v-i  # Split into integer and fractional portions.
    c0r, c0g, c0b = palette[i]
    c1r, c1g, c1b = palette[min(i+1, max_index)]
    dr, dg, db = c1r-c0r, c1g-c0g, c1b-c0b
    return c0r+(f*dr), c0g+(f*dg), c0b+(f*db)  # Linear interpolation.

def colorize(value, minval, maxval, palette):
        """ Convert value to heatmap color and convert it to tkinter color. """
        color = (int(c*255) for c in pseudocolor(value, minval, maxval, palette))
        return '#{:02x}{:02x}{:02x}'.format(*color)  # Convert to hex string.


root = Tk()
root.title('Heatmap')

width, height = 500, 500  # Canvas size.
rows, cols = len(heat_map), len(heat_map[0])
rect_width, rect_height = width // rows, height // cols
border = 1  # Pixel width of border around each.

canvas = Canvas(root, width=width, height=height)
canvas.pack()#goruntuyu gosteren kisim

for y, row in enumerate(heat_map):
    for x, temp in enumerate(row):
        x0, y0 = x * rect_width, y * rect_height
        x1, y1 = x0 + rect_width - border, y0 + rect_height - border
        color = colorize(temp, heat_min, heat_max, palette)
        canvas.create_rectangle(x0, y0, x1, y1, fill=color, width=0)


root.mainloop()

text.txt похож на это.

22 5 9 15 22 20 20 20
22 33 32 15 22 22 20 20
23 34 33 15 22 22 20 20
25 35 35 15 22 25 20 20
12 15 35 15 10 5 20 20
15 40 33 15 3 5 20 15
16 32 25 15 12 22 50 15
13 32 31 15 5 22 23 13

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Вы хотите использовать root.after для многократного вызова функции, которая изменяет цвета каждого прямоугольника.

Я настраивал случайный выбор цветов каждую секунду, чтобы продемонстрировать, как это может работать для вас; Вам, вероятно, придется заменить это обновленными данными, которые регулярно собираются с вашего теплового датчика.

import random

try:
    from tkinter import *
except ModuleNotFoundError:
    from tkinter import *  # Python 3


with open('text.txt', 'r') as f:   # <-- this construct automatically closes the file
    nodes_list = [[int(item) for item in line.split()] for line in f]

heat_map = nodes_list
heat_min = min(min(row) for row in heat_map)
heat_max = max(max(row) for row in heat_map)
print('hello')
palette = (0, 0, 1), (0, .5, 0), (0, 1, 0), (1, .5, 0), (1, 0, 0)


def pseudocolor(value, minval, maxval, palette):
    """ Maps given value to a linearly interpolated palette color. """
    max_index = len(palette)-1
    v = (float(value-minval) / (maxval-minval)) * max_index
    i = int(v); f = v-i
    c0r, c0g, c0b = palette[i]
    c1r, c1g, c1b = palette[min(i+1, max_index)]
    dr, dg, db = c1r-c0r, c1g-c0g, c1b-c0b
    return c0r+(f*dr), c0g+(f*dg), c0b+(f*db)

def colorize(value, minval, maxval, palette):
        """ Convert value to heatmap color and convert it to tkinter color. """
        color = (int(c*255) for c in pseudocolor(value, minval, maxval, palette))
        return '#{:02x}{:02x}{:02x}'.format(*color)


def update_colors():
    for rect in rectangles:
        color = random.choice(colors)            # <--- replace with heat sensor data feed
        canvas.itemconfig(rect, fill=color)
    root.after(1000, update_colors)

root = Tk()
root.title('Heatmap')

width, height = 500, 500  # Canvas size.
rows, cols = len(heat_map), len(heat_map[0])
rect_width, rect_height = width // rows, height // cols
border = 1  # Pixel width of border around each.

canvas = Canvas(root, width=width, height=height)
canvas.pack()#goruntuyu gosteren kisim

rectangles = []    # <-- keep a handle on each of the canvas rectangles
colors = []        # <-- this to have a list of colors to pick from to demonstrate

for y, row in enumerate(heat_map):
    for x, temp in enumerate(row):
        x0, y0 = x * rect_width, y * rect_height
        x1, y1 = x0 + rect_width - border, y0 + rect_height - border
        color = colorize(temp, heat_min, heat_max, palette)
        colors.append(color)
        rectangles.append(canvas.create_rectangle(x0, y0, x1, y1, fill=color, width=0))

update_colors()

root.mainloop()

[Редактировать]:

Если ваши значения датчиков находятся в текстовом файле, вам нужно их извлечь. Это можно сделать, распаковав открытие файла в функции.

псевдокод

def get_sensor_values():
    with open('text.txt', 'r') as f:
        return [[int(item) for item in line.split()] for line in f]  # <-- the nodes list

Тогда в методе update_colors():

def update_colors():
    nodes_list = get_sensor_values()
    for node, rect in zip(nodes_list, rectangles):  # <--- make sure the nodes and the rectangles correspond to the same index in their respective lists
        fill = calculate the color value from the node value   # <-- the same way you already assign an initial color to each rectangle
        canvas.itemconfig(rect, fill=color)
    root.after(1000, update_colors)
0 голосов
/ 03 сентября 2018

Вот попробуй это.

Добавьте эту функцию в свой код.

def repeat():
    global f 
    f = open('text.txt', 'r')
    # This function will be called every 100millisecs 
    root.after(100, repeat) 

и позвоните прямо перед root.mainloop() вот так.

root.after(100, repeat)
root.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...