gpt4 book ai didi

Python Tkinter,显示实时数据

转载 作者:太空宇宙 更新时间:2023-11-04 01:58:25 25 4
gpt4 key购买 nike

我想在 GUI 中显示实时数据,在 tkinter 中。我得到的数据包含一个 list 两个整数 [current, voltage]。我每秒都在获取新数据。

我设法创建了一个 GUI,现在我想知道如何在 GUI Label 小部件(python tkinter)中显示数据并动态更新标签。有什么建议吗

到目前为止,这是我的代码:

#data getting is a list eg. [10, 12]
from tkinter import *
import tkinter.font


#main Window using Tk
win = Tk()

win.title("v1.0")
win.geometry('800x480')
win.configure(background='#CD5C5C')

#Labels
voltage = Label(win, text = "voltage")
voltage.place(x=15, y=100)

current = Label(win, text = "current")
current.place(x=15, y=200)

#display measured values
#how to display here !!!
currentValues = Label(win, text = "want to display somewhere like this")
currentValues.place(x=200, y=100)

voltageValues = Label(win, text = "want to display somewhere like this")
voltageValues.place(x=200, y=200)
mainloop()

最佳答案

如果您想绘制实时数据图表并希望避免使用其他库来为您做这件事,您可能会发现以下内容是创建您自己的图表的启发性起点。在评估标准库中的 math.sin 函数时,该示例绘制了一个完整的值圆。该代码考虑了自动采样、调整大小和根据需要进行更新,并且应该具有相当的响应能力。

#! /usr/bin/env python3
import math
import threading
import time
import tkinter.ttk
import uuid
from tkinter.constants import EW, NSEW, SE


class Application(tkinter.ttk.Frame):
FPS = 10 # frames per second used to update the graph
MARGINS = 10, 10, 10, 10 # internal spacing around the graph

@classmethod
def main(cls):
tkinter.NoDefaultRoot()
root = tkinter.Tk()
root.title('Tkinter Graphing')
# noinspection SpellCheckingInspection
root.minsize(640, 480) # VGA (NTSC)
cls(root).grid(sticky=NSEW)
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()

def __init__(self, master=None, **kw):
super().__init__(master, **kw)
self.display = tkinter.Canvas(self, background='white')
self.display.bind('<Configure>', self.draw)
self.start = StatefulButton(self, 'Start Graphing', self.start_graph)
self.grip = tkinter.ttk.Sizegrip(self)
self.grid_widgets(padx=5, pady=5)
self.data_source = DataSource()
self.after_idle(self.update_graph, round(1000 / self.FPS))
self.run_graph = None

def grid_widgets(self, **kw):
self.display.grid(row=0, column=0, columnspan=2, sticky=NSEW, **kw)
self.start.grid(row=1, column=0, sticky=EW, **kw)
self.grip.grid(row=1, column=1, sticky=SE)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)

def start_graph(self):
self.run_graph = True
threading.Thread(target=self.__simulate, daemon=True).start()
return 'Stop Graphing', self.stop_graph

def stop_graph(self):
self.run_graph = False
return 'Clear Graph', self.clear_graph

def clear_graph(self):
self.data_source.clear()
self.reset_display()
return 'Start Graphing', self.start_graph

# def __simulate(self):
# # simulate changing populations
# for population in itertools.count():
# if not self.run_graph:
# break
# self.data_source.append(population, get_max_age(population, 200))

# def __simulate(self):
# # simulate changing ages
# for age in itertools.count(1):
# if not self.run_graph:
# break
# self.data_source.append(age, get_max_age(250_000_000, age))

def __simulate(self):
# draw a sine curve
for x in range(800):
time.sleep(0.01)
if not self.run_graph:
break
self.data_source.append(x, math.sin(x * math.pi / 400))

def update_graph(self, rate, previous_version=None):
if previous_version is None:
self.reset_display()
current_version = self.data_source.version
if current_version != previous_version:
data_source = self.data_source.copy()
self.draw(data_source)
self.after(rate, self.update_graph, rate, current_version)

def reset_display(self):
self.display.delete('data')
self.display.create_line((0, 0, 0, 0), tag='data', fill='black')

def draw(self, data_source):
if not isinstance(data_source, DataSource):
data_source = self.data_source.copy()
if data_source:
self.display.coords('data', *data_source.frame(
self.MARGINS,
self.display.winfo_width(),
self.display.winfo_height(),
True
))


class StatefulButton(tkinter.ttk.Button):
def __init__(self, master, text, command, **kw):
kw.update(text=text, command=self.__do_command)
super().__init__(master, **kw)
self.__command = command

def __do_command(self):
self['text'], self.__command = self.__command()


def new(obj):
kind = type(obj)
return kind.__new__(kind)


def interpolate(x, y, z):
return x * (1 - z) + y * z


def interpolate_array(array, z):
if z <= 0:
return array[0]
if z >= 1:
return array[-1]
share = 1 / (len(array) - 1)
index = int(z / share)
x, y = array[index:index + 2]
return interpolate(x, y, z % share / share)


def sample(array, count):
scale = count - 1
return tuple(interpolate_array(array, z / scale) for z in range(count))


class DataSource:
EMPTY = uuid.uuid4()

def __init__(self):
self.__x = []
self.__y = []
self.__version = self.EMPTY
self.__mutex = threading.Lock()

@property
def version(self):
return self.__version

def copy(self):
instance = new(self)
with self.__mutex:
instance.__x = self.__x.copy()
instance.__y = self.__y.copy()
instance.__version = self.__version
instance.__mutex = threading.Lock()
return instance

def __bool__(self):
return bool(self.__x or self.__y)

def frame(self, margins, width, height, auto_sample=False, timing=False):
if timing:
start = time.perf_counter()
x1, y1, x2, y2 = margins
drawing_width = width - x1 - x2
drawing_height = height - y1 - y2
with self.__mutex:
x_tuple = tuple(self.__x)
y_tuple = tuple(self.__y)
if auto_sample and len(x_tuple) > drawing_width:
x_tuple = sample(x_tuple, drawing_width)
y_tuple = sample(y_tuple, drawing_width)
max_y = max(y_tuple)
x_scaling_factor = max(x_tuple) - min(x_tuple)
y_scaling_factor = max_y - min(y_tuple)
coords = tuple(
coord
for x, y in zip(x_tuple, y_tuple)
for coord in (
round(x1 + drawing_width * x / x_scaling_factor),
round(y1 + drawing_height * (max_y - y) / y_scaling_factor)))
if timing:
# noinspection PyUnboundLocalVariable
print(f'len = {len(coords) >> 1}; '
f'sec = {time.perf_counter() - start:.6f}')
return coords

def append(self, x, y):
with self.__mutex:
self.__x.append(x)
self.__y.append(y)
self.__version = uuid.uuid4()

def clear(self):
with self.__mutex:
self.__x.clear()
self.__y.clear()
self.__version = self.EMPTY

def extend(self, iterable):
with self.__mutex:
for x, y in iterable:
self.__x.append(x)
self.__y.append(y)
self.__version = uuid.uuid4()


if __name__ == '__main__':
Application.main()

关于Python Tkinter,显示实时数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56275043/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com