sightmachine/SimpleCV

Error thrown when the isDone() method is called in the Display object

eleventhHour opened this issue · 2 comments

Multiple people, especially beginners, are having this issue which can be seen on the forums: http://help.simplecv.org/question/1505/error-with-example-from-page-25/ .

Solution: Open the Display.py file, which contains the display object used in the program. For me (on a windows machine), is located at: C:\Python27\lib\site-packages\SimpleCV\Display.py On line 599, in the def checkEvents(self): there is a pg.quit() function call then a on line 600 there is self.done =True. After that line add a return statement.

The code in this file then will look like this:

    def checkEvents(self):
        """
        **SUMMARY**

        CheckEvents checks the pygame event queue and sets the internal display
        values based on any new generated events.

        .. warning:: 
          This method must be called (or :py:meth:`isDone` or :py:meth:`isNotDone`) to
          perform mouse event checking. 

        **RETURNS**

        Nothing.
        """
        self.mouseWheelUp = self.mouseWheelDown = 0
        self.lastLeftButton = self.mouseLeft
        self.lastRightButton = self.mouseRight
        self.leftButtonDown = None
        self.leftButtonUp = None
        self.rightButtonDown = None
        self.rightButtonUp = None

        for event in pg.event.get():
            if event.type == pg.QUIT:
                pg.quit()               #line 599
                self.done = True   #line 600
                return                 ######THIS LINE WAS ADDED!!!! prevents another pygame call######
            if event.type == pg.MOUSEMOTION:
                self.mouseRawX = event.pos[0]
                self.mouseRawY = event.pos[1]
                x = int((event.pos[0]-self.xoffset)*self.xscale)
                y = int((event.pos[1]-self.yoffset)*self.yscale)
                (self.mouseX,self.mouseY) = self._clamp(x,y)
                self.mouseLeft, self.mouseMiddle, self.mouseRight = event.buttons
            if event.type == pg.MOUSEBUTTONUP:

                self._setButtonState(0, event.button)

            if event.type == pg.MOUSEBUTTONDOWN:
                self._setButtonState(1, event.button)

        pressed = pg.key.get_pressed()

        if( self.lastLeftButton == 0 and self.mouseLeft == 1 ):
            self.leftButtonDown = (self.mouseX,self.mouseY)
        if( self.lastLeftButton == 1 and self.mouseLeft == 0 ):
            self.leftButtonUp = (self.mouseX,self.mouseY)

        if( self.lastRightButton == 0 and self.mouseRight == 1 ):
            self.rightButtonDown = (self.mouseX,self.mouseY)
        if( self.lastRightButton == 1 and self.mouseRight == 0 ):
            self.rightButtonUp = (self.mouseX,self.mouseY)

        #If ESC pressed, end the display
        if(pressed[27] == 1):
            self.done = True

What is happening is the program is closing all modules created by pygame (including the window) when pg.quit() is called, then the progam calls a pygame function again on line 615: pressed = pg.key.get_pressed(). Since all the modules are closed, the pygame video system is no longer initialized and therefore an error is thrown that the pygame video system is not initialized. By adding a return statement, pressed = pg.key.get_pressed() is never called and no error is thrown.

I'm completely new to SimpleCV but playing with the examples in Chapter 2 I found this related issue: pressing ESC returns from the function but doesn't take down the display window. I'd guess anytime self.down is set to True pg.quit() should be called(?)

saschwarz - Yes, I would think you would want pygame to quit when the ESC key is pressed so adding

elif event.type == KEYDOWN and event.key == K_ESCAPE:
    pg.quit()
    return

would make the program exit gracefully when when that key is pressed.