在 python 和 tkinter 中使用 while 循环持续更新传感器数据

Continous update of sensor data using while loop in python and tkinter

我正在使用 NI 仪器读取数据并将其显示在 GUI 上。用过tkinter。但是找不到使用 while 循环更新数据的方法。

import nidaqmx
import time
from tkinter import *
master = Tk()
while True:
    with nidaqmx.Task() as task:
        task.ai_channels.add_ai_voltage_chan("Dev1/ai0")
        print('1 Channel 1 Sample Read: ')
        data = task.read()
        sensor_value ='%.2f' % data #said sensor value
        master.minsize(width=400, height=400)
        w = Label(master, text=sensor_value) #shows as text in the window
        w.pack() #organizes widgets in blocks before placing them in the parent.          
        time.sleep(5)
        mainloop()

试试这个代码:

import time
from tkinter import *
import nidaqmx

master = Tk()

def test():
    while True:
        with nidaqmx.Task() as task:
            task.ai_channels.add_ai_voltage_chan("Dev1/ai0")
            print('1 Channel 1 Sample Read: ')
            data = task.read()
            sensor_value = '%.2f' % data  # said sensor value
            
            w['text'] = sensor_value
            master.update()
            time.sleep(2)

w = Label(master)
w.pack()
btn = Button(text="Start read from sensor", command=test)
btn.pack()
mainloop()

您可能需要第二个线程来轮询传感器。

import nidaqmx
import time
import threading
from tkinter import *


stop_signal = threading.Event()


def read_loop():
    with nidaqmx.Task() as task:
        task.ai_channels.add_ai_voltage_chan("Dev1/ai0")
        while True:
            data = task.read()
            label["text"] = "%.2f" % data

            # Wait for the signal, or 5 seconds
            if stop_signal.wait(timeout=5):
                break  # If the signal was set, break


# Build window
master = Tk()
master.minsize(width=400, height=400)
label = Label(master, text="")
label.pack()

# Set up & start reading thread
threading.Thread(target=read_loop).start()

try:
    # Enter Tk main loop
    mainloop()
finally:
    # Clean up afterwards
    stop_signal.set()

请记住 mainloop() 正在阻塞,因此 time.sleep() 没有用,因为您不会返回到 task.read() 行。 考虑使用线程库中的 Thread 模块,像这样导入它:

from threading import Thread

或按照其他人的建议使用按钮刷新值。

使用 Tkinter 我们应该避免使用线程,while 使用 root.update() 循环这不是我们不能使用它们但不建议使用使用 Tkinter 本身提供的 after(delay_ms, callback=None, *args) 方法是有原因的。

现在看你的代码,你的代码中几乎没有问题。

  1. while 循环中,您 每 5 秒创建一个 Label 而不是创建一个标签并更新值 循环内该标签的 w['text'] = '...'w.configure(text='...').

  2. 不要把mainloop放在循环里面,而是在最后一行调用在您的案例中使用主要 window 的实例 master (master.mainloop()).

  3. master.minsize(width=400, height=400)相同,你不必每5秒告诉master window设置最小尺寸到 400x400 应该调用一次 如果不决定将最小尺寸更改为不同的几何图形。

您的代码应如下所示。

import nidaqmx
from tkinter import *

master = Tk()
master.minsize(width=400, height=400)
w = Label(master) #shows as text in the window
w.pack() #organizes widgets in blocks before placing them in the parent.   

def run():
    with nidaqmx.Task() as task:
        task.ai_channels.add_ai_voltage_chan("Dev1/ai0")
        print('1 Channel 1 Sample Read: ')
        data = task.read()
        w['text'] = '%.2f' % data #said sensor value
    master.after(5000, run)

run() # run the function once.
master.mainloop()

这应该是正确的方法,因为我不能运行你的代码如果有任何问题,否则请告诉我。