2

The implementation is pasted below. However, each time I actually input something in the console, I get this error:

        while executing
    "::tcl::Bgerror {out of stack space (infinite loop?)} {-code 1 -level 0 -errorcode NONE -errorinfo {out of stack space (infinite loop?)
        while execu..."
    error in background error handler:

out of stack space (infinite loop?)

This is used by another application(Matplotlib GUI), that instantiates ConsoleInput, and then uses the most recent user entry for itself.

Why is this error happening, and how can I fix ConsoleInput? Is there a way to check if there is pending input, and only read then, rather than loop constantly?

import threading


class ConsoleInput(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True
        self.exit = False
        self.most_recent_entry = None

    def run(self):
        while not self.exit:
            self.most_recent_entry = raw_input()

Here is the relevant part of the GUI that's using the console input:

def __init__(self):
    self.console_input = ConsoleInput()
    self.console_input.start()
    self.run()

def run(self):
    self.figure = plt.figure(figsize=(16, 8))
    self.figure.canvas.set_window_title(self.title)
    self.gen_data()
    plt.connect('button_press_event', self.on_fig_update_event)
    plt.connect('motion_notify_event', self.on_fig_update_event)
    plt.tight_layout()
    plt.show()

def gen_data(self):
    if self.console_input.most_recent_entry:
        print self.console_input.most_recent_entry:
11
  • Is there an infinite loop that's editing a GUI element somewhere? Maybe in the code that's actually using the ConsoleInput instance? Commented Aug 22, 2014 at 17:28
  • Yes, there is. The input from the console is then used to update a gui appropriately. But I did not get this error before including the console input element. Commented Aug 22, 2014 at 17:29
  • Can you share the code that's using ConsoleInput? I think that's probably the piece that needs to change. Commented Aug 22, 2014 at 17:31
  • I did. The interesting thing is that the error happens only after I enter something in console. Commented Aug 22, 2014 at 17:51
  • 1
    this seems like bad design ... I suspect you can find a key_press_event for matplotlib ... Commented Aug 22, 2014 at 17:59

1 Answer 1

2

[edit] Based on new information you have provided ... try this solution (original solutions found below)

class SomeClass:
    def __init__(self):
        #this stuff is bad dont do it
        #self.console_input = ConsoleInput()
        #self.console_input.start()
        self.run()
    def on_console(self,evt):

        print "data = ",self.var.get()

    def run(self):
        self.figure = plt.figure(figsize=(16, 8))
        self.figure.canvas.set_window_title("a title")
        plt.subplots_adjust(bottom=0.25) # Make space for stuff
        plt.plot([1,2,3],[5,5,6])
        #add stuff to our frame
        self.var = StringVar() #hold user variable
        b = Button(self.figure.canvas.get_tk_widget(),text="Update Chart!")
        b.pack(side="bottom",fill="both",padx=4,pady=1)
        slider = Entry(self.figure.canvas.get_tk_widget(),textvariable = self.var)
        slider.pack(side="bottom", fill='both',  padx=4, pady=4)
        b.bind("<Button-1>",self.on_console)
        plt.show()

two things something like this maybe what you are looking for ... but in general you really shouldnt be reading stdin with gui programs ...

A much better solution is to get the info from the gui something like

from matplotlib import pyplot as plt
import tkSimpleDialog
class SomeClass:
    def __init__(self):
        #this stuff is bad dont do it
        #self.console_input = ConsoleInput()
        #self.console_input.start()
        self.run()
    def on_console(self,evt):
        data = tkSimpleDialog.askstring("HELLO?","You?")
        print data
        #do something with the data (and self.figure perhaps)
    def run(self):
        self.figure = plt.figure(figsize=(16, 8))
        self.figure.canvas.set_window_title("a title")
        plt.connect('key_release_event', self.on_console)
        plt.show()

however if you really want to use console input you should probably use the cmd module

import cmd
from matplotlib import pyplot as plt
class SomeClass:
        def __init__(self):
            #this stuff is bad dont do it
            #self.console_input = ConsoleInput()
            #self.console_input.start()
            self.run()
        def on_console(self,evt):
            print "EVT:",evt
            MyCmdInterface(self).cmdloop()
        def run(self):
            self.figure = plt.figure(figsize=(16, 8))
            self.figure.canvas.set_window_title("a title")
            plt.connect('key_release_event', self.on_console)
            plt.show()

class MyCmdInterface(cmd.Cmd):
    """Simple command processor example."""
    prompt="CMD:"
    def __init__(self,guiInst):
        print "MPL Interactive Command Interface! type HELP for help."
        cmd.Cmd.__init__(self)
        self.gui = guiInst
    def do_HELP(self,line):
        print "Some Help Message"
    def do_SET(self, line):
        assert "=" in line,"SET COMMANDS REQUIRE <varName>=<valName>"
        var,val = line.split("=",1)
        #do something
    def do_NEWDATA(self,line):
        newdata = map(float,line.split(","))
        print "SET latest_values = %s"%newdata
        self.gui.latest_values = newdata
        #do something with new data

    def do_EOF(self, line):
        return True
    #aliases for exit
    do_EXIT = do_exit = do_QUIT = do_quit = do_DONE = do_done = do_EOF

if __name__ == '__main__':
    s = SomeClass()
    s.run()

this also demonstrates what a short runnable code example looks like

Sign up to request clarification or add additional context in comments.

5 Comments

Here I was told it was impossible: stackoverflow.com/questions/25449398/…
Also, your solution does not work. It freezes the app, and does not really read anything. Not sure if I should accept it, because otherwise in the future people won't answer my questions.
its a modal dialog it sits on top of the app and blocks input until it is closed ... if you want it non-modal you will need to create your own simple tkinter frame asking for input (assuming default tkinter backend ... ) I think you need to better define your problem if you want a better answer
Can you please look at this while you're at it stackoverflow.com/questions/25454853/… I think it has to do with the fact that at start, when it has only a handful of data points, it can happen that all y-values are same, but why is that a problem?
no idea and you do not provide enough information to get an answer ... but see edit on this solution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.