在 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)
方法是有原因的。
现在看你的代码,你的代码中几乎没有问题。
在 while
循环中,您 每 5 秒创建一个 Label
而不是创建一个标签并更新值 循环内该标签的 w['text'] = '...'
或 w.configure(text='...')
.
不要把mainloop
放在循环里面,而是在最后一行调用在您的案例中使用主要 window 的实例 master
(master.mainloop()
).
与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()
这应该是正确的方法,因为我不能运行你的代码如果有任何问题,否则请告诉我。
我正在使用 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)
方法是有原因的。
现在看你的代码,你的代码中几乎没有问题。
在
while
循环中,您 每 5 秒创建一个Label
而不是创建一个标签并更新值 循环内该标签的w['text'] = '...'
或w.configure(text='...')
.不要把
mainloop
放在循环里面,而是在最后一行调用在您的案例中使用主要 window 的实例master
(master.mainloop()
).与
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()
这应该是正确的方法,因为我不能运行你的代码如果有任何问题,否则请告诉我。