我们如何根据订阅的主题消息的变化动态改变Tkinter标签小部件中的文本?
How do we dynamically change the text in label widget of Tkinter according to the change of subscribed topic message?
我想根据我的节点订阅的主题消息更改我的标签文本。但问题是标签中的文字并没有随着主题消息的变化而变化。下面给出了我的部分代码:(我使用代码从 https://bytes.com/topic/python/answers/629499-dynamically-displaying-time-using-tkinter-label 动态更改标签中的文本)
v = StringVar()
v.set(distance)
self.clock = Label(frame, font=('times', 20, 'bold'), bg='green', textvariable = v)
self.clock.pack(fill=BOTH, expand=1)
rate = rospy.Rate(2)
while not rospy.is_shutdown():
rospy.Subscriber("distance", Float32, self.callback)
v.set(distance)
print("distance = %f", distance)
frame.update_idletasks()
rate.sleep()
好吧,您的代码(或者至少是您发布的部分)看起来很乱。
ROS 说话,
define your subscriber in the initialization of the node
(不在里面
while 循环,它会创建多个订阅者!)
create a callback to get the messages
在那个话题下交流阅读留言
update your label
相应地。
话虽这么说,但这里有一个代码的示例:(填空)
#!/usr/bin/env python
import rospy
from std_msgs.msg import Float32
def callback(data):
distance = data.data
rospy.loginfo(rospy.get_caller_id() + "distance = ", distance )
#here update your label, I assume the following (maybe not correct)
v = StringVar()
v.set(distance)
self.clock = Label(frame, font=('times', 20, 'bold'), bg='green', textvariable = v)
self.clock.pack(fill=BOTH, expand=1)
def listener():
rospy.init_node('listener', anonymous=True)
rospy.Subscriber("distance", Float32, self.callback)
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
if __name__ == '__main__':
listener()
共享示例 ROS 订阅者以读取 1 个传感器并使用 tkinter 和 Class 显示结果。显示将更新 1/秒或您设置的任何值。
import tkinter as tk
from tkinter import ttk
import time
from random import randint
import rospy
from std_msgs.msg import Int16
"""
subscribes to a ROS topic (/front_angle_low_res) which in my case is outputing an integer result and displays the result in a tkinter window
credit: https://www.pythontutorial.net/tkinter/tkinter-after/
credit: https://www.youtube.com/watch?v=EAAd5vXA8lE&t=260s
before running make sure to $ rostopic echo /front_angle_low_res to make sure data is available
This script can be started from the folder it resides in with $ python3 sensor_display.py
"""
class Display_Sensor_1(tk.Tk):
def __init__(self):
super().__init__()
self.sub = rospy.Subscriber("/front_angle_low_res", Int16, self.callback_sensor_1)
self.sensor_1_data = tk.IntVar()
# configure the root window
self.title('Sensor 1 Data')
self.resizable(0, 0)
self.geometry('250x80')
self['bg'] = 'black'
# change the background color to black
self.style = ttk.Style(self)
self.style.configure('TLabel', background='black', foreground='red')
self.label = ttk.Label(self, text=self.get_sensor_data(), font=('Digital-7', 20))
self.label.pack(expand=True)
self.label.after(1000, self.update) # schedule an update every 1 second
def callback_sensor_1(self, data):
self.sensor_1_data = data.data
#print(self.sensor_1_data)
#rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
def get_sensor_data(self):
return self.sensor_1_data
def update(self):
""" update the label every 1 second """
self.label.configure(text=self.get_sensor_data())
self.label.after(1000, self.update) # schedule another timer
if __name__ == "__main__":
rospy.init_node('listener', anonymous=True)
sensor = Display_Sensor_1()
sensor.mainloop()
我想根据我的节点订阅的主题消息更改我的标签文本。但问题是标签中的文字并没有随着主题消息的变化而变化。下面给出了我的部分代码:(我使用代码从 https://bytes.com/topic/python/answers/629499-dynamically-displaying-time-using-tkinter-label 动态更改标签中的文本)
v = StringVar()
v.set(distance)
self.clock = Label(frame, font=('times', 20, 'bold'), bg='green', textvariable = v)
self.clock.pack(fill=BOTH, expand=1)
rate = rospy.Rate(2)
while not rospy.is_shutdown():
rospy.Subscriber("distance", Float32, self.callback)
v.set(distance)
print("distance = %f", distance)
frame.update_idletasks()
rate.sleep()
好吧,您的代码(或者至少是您发布的部分)看起来很乱。
ROS 说话,
define your subscriber in the initialization of the node
(不在里面 while 循环,它会创建多个订阅者!)create a callback to get the messages
在那个话题下交流阅读留言update your label
相应地。
话虽这么说,但这里有一个代码的示例:(填空)
#!/usr/bin/env python
import rospy
from std_msgs.msg import Float32
def callback(data):
distance = data.data
rospy.loginfo(rospy.get_caller_id() + "distance = ", distance )
#here update your label, I assume the following (maybe not correct)
v = StringVar()
v.set(distance)
self.clock = Label(frame, font=('times', 20, 'bold'), bg='green', textvariable = v)
self.clock.pack(fill=BOTH, expand=1)
def listener():
rospy.init_node('listener', anonymous=True)
rospy.Subscriber("distance", Float32, self.callback)
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
if __name__ == '__main__':
listener()
共享示例 ROS 订阅者以读取 1 个传感器并使用 tkinter 和 Class 显示结果。显示将更新 1/秒或您设置的任何值。
import tkinter as tk
from tkinter import ttk
import time
from random import randint
import rospy
from std_msgs.msg import Int16
"""
subscribes to a ROS topic (/front_angle_low_res) which in my case is outputing an integer result and displays the result in a tkinter window
credit: https://www.pythontutorial.net/tkinter/tkinter-after/
credit: https://www.youtube.com/watch?v=EAAd5vXA8lE&t=260s
before running make sure to $ rostopic echo /front_angle_low_res to make sure data is available
This script can be started from the folder it resides in with $ python3 sensor_display.py
"""
class Display_Sensor_1(tk.Tk):
def __init__(self):
super().__init__()
self.sub = rospy.Subscriber("/front_angle_low_res", Int16, self.callback_sensor_1)
self.sensor_1_data = tk.IntVar()
# configure the root window
self.title('Sensor 1 Data')
self.resizable(0, 0)
self.geometry('250x80')
self['bg'] = 'black'
# change the background color to black
self.style = ttk.Style(self)
self.style.configure('TLabel', background='black', foreground='red')
self.label = ttk.Label(self, text=self.get_sensor_data(), font=('Digital-7', 20))
self.label.pack(expand=True)
self.label.after(1000, self.update) # schedule an update every 1 second
def callback_sensor_1(self, data):
self.sensor_1_data = data.data
#print(self.sensor_1_data)
#rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
def get_sensor_data(self):
return self.sensor_1_data
def update(self):
""" update the label every 1 second """
self.label.configure(text=self.get_sensor_data())
self.label.after(1000, self.update) # schedule another timer
if __name__ == "__main__":
rospy.init_node('listener', anonymous=True)
sensor = Display_Sensor_1()
sensor.mainloop()