Search code examples
pythontkinterlabelros

How do we dynamically change the text in label widget of Tkinter according to the change of subscribed topic message?


I wanted to change the text of my label according to the topic message to which my node subscribes. But the problem is that the text in the label is not changing with the change of topic message. A portion of my code is given below:(I used the code to dynamically change the text in the label from 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()

Solution

  • Well, your code (or at least the portion you posted) seems to be a messy one.

    ROS talking,

    • define your subscriber in the initialization of the node (not inside the while loop, that will create multiple subscribers instead!)
    • create a callback to get the messages exchanged under that topic read the message
    • update your label accordingly.

    That being said, here's an example of how the code should look like : (fill in the blanks)

    #!/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()