0

I am writing tkinter python program for turning on and off the publisher. I need to turn on and off the publisher using a button. If am writing using while loop, the entire gui freezes, I am unable to operate anything. Please give me some suggestions.

dummy = Button(master, text="dummy", relief='groove',command=self.pub_values)
def pub_values(self):
    self.pub = rospy.Publisher('/gateway/RigPLC2Seq', Int32MultiArray, queue_size=10)
    rospy.init_node('talker_int', anonymous=True)
    rate = rospy.Rate(1)  # 10hz
    self.var = Int32MultiArray()
    self.var.data = []
    ls = self.extract_values()
    self.var.data = ls
    self.on = True
    while self.on == True:
        rospy.loginfo(self.var)
        self.pub.publish(self.var)
        rate.sleep()
j_4321
  • 15,431
  • 3
  • 34
  • 61
rmk_pyth
  • 1
  • 5
  • I think you could replace the `while` + `sleep` by tkinter's `after` method. If you could provide a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) it would be easier for me to tell you how. – j_4321 Nov 27 '18 at 08:13
  • Why is it even necessary to publish the same data multiple times? Use events from your GUI elements. PushButton is Clicked publish one message with the info and so on. – Darkproduct Nov 27 '18 at 13:14
  • Thanks, @j_4321. I am not using .sleep() anymore. But the publishing should happen continuously till I press another button to stop it. – rmk_pyth Nov 27 '18 at 17:31
  • Thanks Darkproduct. I am new to python and tkinter. Could you please share a event binder example with continuos publishing of data. – rmk_pyth Nov 27 '18 at 17:33

2 Answers2

0

Your solution is not far fetched.

  1. you set self.on to True, then you have a while loop that checks to the value of self.on which if True should freeze(.sleep()) your GUI.

Your code is obeying just what you typed in.

Solution:

You must have a condition in your while loop that changes the value of self.on to False, if you don't the while loop will never stop being executed. Example:

counter=1
self.on = True
while self.on == True:
    rospy.loginfo(self.var)
    self.pub.publish(self.var)
    rate.sleep()
    if counter==10:
        self.on=False
    counter++

With the above code, I want the loop to run 10 times, after that self.on becomes False and the while loop exits, which also unfreezes your GUI(.sleep() no longer runs)

  1. More importantly is that suggested by @j_4321 above, .sleep() freezes the GUI as long as it is running, you will be better served using the .after() method. This should help you learn about the .after() method if you so desire to use it.
Samuel Kazeem
  • 787
  • 1
  • 8
  • 15
  • Thanks, Chuck G. Could please tell me some suggestions: I need to start publishing continuously with a button until I press the stop button for stopping it in the same GUI. – rmk_pyth Nov 27 '18 at 17:33
  • If you have stopped using `.sleep()` as you stated above, do post your current working code, it is difficult to get help when you do not give your helpers something concrete to work with. As @j_4321 said, post it in an [MCVE](https://stackoverflow.com/help/mcve) format – Samuel Kazeem Nov 27 '18 at 18:52
0

You can use after to replace the while loop. While self.on is true, publish is executed and rescheduled. The button command toggles self.on and relaunches publish when self.on is set back to true:

import tkinter as tk

class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)

        self.on = False

        self.button = tk.Button(self, text='Start', command=self.start_stop)
        self.button.pack()

    def start_stop(self):
        if self.on:
            self.button.configure(text='Start')
            self.on = False  # stop publish
        else:
            self.button.configure(text='Stop')
            self.on = True
            self.publish()  # relaunch publish

    def publish(self):
        if self.on:
            print('publish')
            self.after(1000, self.publish)

App().mainloop()
j_4321
  • 15,431
  • 3
  • 34
  • 61