rospy and Tkinter - spin() and mainloop()
I want to write a rospy node that uses Python's GUI toolkit Tkinter, problem is that rospy.spin() and top.mainloop() are both blocking calls.
I thought of starting one and setting an interrupt to start the other, like:
top.after(50, rospy.spin )
top.mainloop()
This successfully starts both loops, but once rospy.spin() starts it completely takes control from Tkinter (until I hit ctrl+c, then Tkinter resumes). What I really want is a rospy.spinOnce() that I can call on Tkinter's repaint cycle, but I gather there isn't such a thing.
Is there a good way to have both top.mainloop() and rospy.spin() running in the same thread? Or at least a work-a-round?
Edit: I found a work-a-round by forking rospy.spin() into it's own thread and protecting all my variables inside the ros callbacks with mutexes like so:
from threading import Thread, Lock
mutex = Lock()
def rosClbk(data) :
mutex.aquire()
_var = var
mutex.release()
# do processing on _var
def main() :
...
t = Thread(target = rospy.spin )
t.start()
top.mainloop()
This makes the program a bit hard to kill (since ros no longer responds to ctrl+c), but otherwise seems to work fine. Is this too dirty? Is there a better way?