[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Some advice for closing Pygame from within an application?



Hi Luke,

Thanks for the quick response, it's true I should know better for giving details... Here's a simplified code that respects the way I implemented the game and how it's used. The precise issue is that the escape key has no effect and closing the game window kills everything, app main window and all... I'm going to look more at why the Escape key isn't interpreted, I haven't looked into it closely..
Hope this is more helpful and thanks again:


import sys

from PyQt4.QtCore import *
from PyQt4.QtGui  import *

import pygame
from   pygame.locals import *

#a thread called elsewhere due to other reasons
class mythread(QThread):

    def __init__(self, game_owner, parent=None):
        super(mythread, self).__init__(parent)
        
        self.halted = False
        self.mutex = QMutex()
        self.game_owner = game_owner

    def initialize(self):
        self.halted = False

    def run(self):
        self.upd_game()

    def upd_game(self):
        while not self.halted:
            #restart game if over and replay is enabled
            if (self.game_owner.game !=None):
                if (not self.game_owner.game.gameover):
                    self.game_owner.game.run()
                    #an escape or quit game can happen during a run...
                else:
                    #need to close pygame window only
                    #try:
                    #    self.game_owner.game.quit()
                    #except:
                    #    pass
                    self.game_owner.game = None

    def stop(self):
        try:
            self.mutex.lock()
            self.halted = True
        finally:
            self.mutex.unlock()

##Game - counts Up and DOwn keys pressed
class mygame:

    def __init__(self):
        #game variables and flags
        self.nb_up = 0
        self.nb_down   = 0
        self.gameover  = False
        self.replay    = True
        
        #Clock
        self.clock = pygame.time.Clock()
        
        #Display configuration
        self.screen = pygame.display.set_mode((200,200))
        pygame.display.set_caption("Have fun with my bogus game!")
        
        #background entity
        self.background = "">
        self.background = "">
        self.background.fill((0,0,0))
        
        #Score board label
        pygame.font.init()
        text          = "Up: "+ str(self.nb_up) + "   vs.   Down: " + str(self.nb_down)
        self.lbl_font = pygame.font.SysFont("Comic Sans MS", 12)
        self.label    = self.lbl_font.render(text, 1, (200,200,200))

    ##Update score label
    def upd_score(self):
        text          = "Up: "+ str(self.nb_up) + "   vs.   Down: " + str(self.nb_down)
        self.label    = self.lbl_font.render(text, 1, (200,200,200))

    ##Interpret pressed key
    def interpret_key(self):
        #get pressed key
        keystate = pygame.key.get_pressed()
        
        if keystate[pygame.locals.K_UP]:
            self.nb_up += 1
        
        if keystate[pygame.locals.K_DOWN]:
            self.nb_down += 1
        #player wants to stop game - no effect?
        if keystate[pygame.locals.K_ESCAPE]:
            return False
        
        return True

   ##Method called in thread
    def run(self):
        
        #tick the clock
        self.clock.tick(30)
        
        #update key score or exit 
        if not self.interpret_key():
            self.replay   = False
            self.gameover = True
            return
        
        #Quit the game
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.gameover = True
                self.replay   = False
                
        #update graphical components
        self.screen.blit(self.background, (0,0))
        self.upd_score()
        self.screen.blit(self.label, (10,10))
        pygame.display.flip()
        
    ##quit game
    def quit(self):
        pygame.quit()
        #pygame.display.quit()

##main window class
class mainwin(QMainWindow):
    
    def __init__(self, parent=None):
        QMainWindow.__init__(self)
        
        #Main window settings
        self.setWindowTitle("Trying to exit pygame")
        self.setMinimumSize(300 , 300)
        #self.move(0,0)
        
        self.winthread = None
        self.game = None
        
        #menu
        #Create the Menu Bar
        self.menu = self.menuBar()
        
        #Create the File menu entry in the bar
        self.file_menu = self.menu.addMenu('&File')
        #Create the File entry actions
        self.file_quit = self.file_menu.addAction('&Quit')
        self.file_quit.setShortcut(QKeySequence('Ctrl+Q'))
        self.connect(self.file_quit, SIGNAL("triggered()"), self.quit)
        
        #toolbar
        self.toolbar = QToolBar(self)
        self.toolbar.setObjectName("toolbar")
        self.addToolBar(self.toolbar)
        
        #add menu actions to toolbar
        self.toolbar.addAction(self.file_quit)

        #main widget
        self.mainWidget  = QWidget()
        self.setCentralWidget(self.mainWidget)
        
        layv = QVBoxLayout()
        
        self.b_startgame = QPushButton('Go!', self.mainWidget)
        self.b_startgame.setMaximumWidth(100)
        self.connect(self.b_startgame, SIGNAL('clicked()'), self.start_game)
        layv.addWidget(self.b_startgame)
        
        self.mainWidget.setLayout(layv)
        
    ##exit app window
    def quit(self):
        self.close()
    
    #start game and thread calling its run
    def start_game(self):
        self.winthread = mythread(self)
        self.winthread.start()
        self.game = mygame()
    

if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setApplicationName('TestPyGame')
    
    form = mainwin()
    form.show()
    app.exec_()