Partage
  • Partager sur Facebook
  • Partager sur Twitter

probleme interface graphique pygame

Sujet résolu
    10 janvier 2018 à 21:48:09

    Bonjour a tous ! 

    Alors voila je crée une interface graphique  qui produit un truc du style

    nombre de joueur < nb >

    nb de colonne < nb >

    etc 

           start

    seulement voila a chaque fois seul le premier appelle a ma fonction click fonctionne pour les autres rien j'ai inersé l'ordre des " if click ....." et c'est toujours le permier dans le code qui marche et encore il faut un peu spam click avant d'obtnenir un resultat

    c'est un système que j'avais deja utilisé sur une interface graphique d'un ecran tactile arduino et ça marchait pas mal alors je pense que le probleme vient plutot d'une particularité de python / pygame

    alors si jamais vous avez une idée pour que ça fonctionne ou si vous avez une autre technique pour faire des menus je suis preneur 

    merci d'avance ! 

    ###################
    ##### IMPORTS #####
    ###################
    
    import pygame, sys
    from pygame.locals import *
    pygame.init()
    clock = pygame.time.Clock()
    #####################
    ##### CONSTANTS #####
    #####################
    
    W_NAME = "Chain Reaction"
    W_SIZE = (1280,720)
    
    nbplayer = 4
    nbrows = 8
    nbcolumns = 5
    
    # Colors
    
    WHITE = (255,255,255)
    ROUGE = (255,0,0)
    VERT = (0,255,0)
    BLEU = (0,0,255)
    JAUNE = (255,255,0)
    MAGENTA = (255,0,255)
    CYAN = (0,255,255)
    ORANGE = (255,106,0)
    VIOLET = (157,0,255)
    
    
    #=============
    # taille < w24 h23px
    #==========
    def click(x,y,width,height):
    
         for event in pygame.event.get():
            if event.type == MOUSEBUTTONDOWN and event.button == 1:
                mouseX = event.pos[0]
                mouseY = event.pos[1]
                print(mouseX,mouseY)
                if mouseX > x and mouseX < x + width and mouseY > y and mouseY < y + height:
                    return True
                else:
                    return False
    
    
    def initGame(mySurface, screen):
    
        global nbplayer
        global nbrows
        global nbcolumns
    
    
    
        displayTxt(mySurface, screen, "select number of player", WHITE, 100, 100, 48,"HACKED.ttf")
        displayTxt(mySurface, screen, "Select number of rows", WHITE, 100, 250, 48,"HACKED.ttf")
        displayTxt(mySurface, screen, "select number of columns", WHITE, 100, 400, 48,"HACKED.ttf")
        displayTxt(mySurface, screen, "START", ROUGE, 550, 600, 70,"HACKED.ttf")
        #selecteur ligne 1
        displayTxt(mySurface, screen, "<", WHITE, 800, 100, 70,"HACKED.ttf")
        displayTxt(mySurface, screen, str(nbplayer), WHITE, 900, 100, 70,"arial.ttf")
        displayTxt(mySurface, screen, ">", WHITE, 1000, 100, 70,"HACKED.ttf")
        # selecteur ligne 2
        displayTxt(mySurface, screen, "<", WHITE, 800, 250, 70,"HACKED.ttf")
        displayTxt(mySurface, screen, str(nbrows), WHITE, 900, 250, 70,"arial.ttf")
        displayTxt(mySurface, screen, ">", WHITE, 1000, 250, 70,"HACKED.ttf")
        # selecteur ligne 3
        displayTxt(mySurface, screen, "<", WHITE, 800, 400, 70,"HACKED.ttf")
        displayTxt(mySurface, screen, str(nbcolumns), WHITE, 900, 400, 70,"arial.ttf")
        displayTxt(mySurface, screen, ">", WHITE, 1000, 400, 70,"HACKED.ttf")
    
        if click(800,100,50,50 ) == 1 and nbplayer > 2:
            nbplayer -= 1
            mySurface.fill((0, 0, 0))
            displayTxt(mySurface, screen, str(nbplayer), WHITE, 900, 100, 70, "arial.ttf")
        if click(1000,100,50,50 ) == 1 and nbplayer < 8:
            nbplayer += 1
            mySurface.fill((0, 0, 0))
            displayTxt(mySurface, screen, str(nbplayer), WHITE, 900, 100, 70, "arial.ttf")
        if click(800,250,50,50 ) == 1 and nbrows > 1:
            nbrows -= 1
            mySurface.fill((0, 0, 0))
            displayTxt(mySurface, screen, str(nbrows), WHITE, 900, 250, 70, "arial.ttf")
        if click(1000,250,50,50 ) == 1:
            nbrows += 1
            mySurface.fill((0, 0, 0))
            displayTxt(mySurface, screen, str(nbrows), WHITE, 900, 250, 70, "arial.ttf")
        if click(800,400,50,50 ) == 1 and nbcolumns > 1:
            nbcolumns -= 1
            mySurface.fill((0, 0, 0))
            displayTxt(mySurface, screen, str(nbcolumns), WHITE, 900, 400, 70, "arial.ttf")
        if click(1000,400,50,50 ) == 1:
            nbcolumns += 1
            mySurface.fill((0, 0, 0))
            displayTxt(mySurface, screen, str(nbcolumns), WHITE, 900, 400, 70, "arial.ttf")
    
    
    
    
    def displayTxt(mySurface, screen, text, color, x, y, fontWeight,tipo):
        font = pygame.font.Font(tipo, fontWeight)
        display = font.render(text, True, color)
        position = display.get_rect()
        position.topleft = (x, y)
        mySurface.blit(display, position )
        screen.blit(mySurface, (0, 0))
        pygame.display.flip()
    
    
    def drawCell(mySurface, gameBoard,n, m, i, j):
        pass
    
    
    def main():
    
        screen = pygame.display.set_mode(W_SIZE)
        mySurface = pygame.Surface(screen.get_size())
        mySurface = mySurface.convert()
        mySurface.fill((0, 0, 0))
        pygame.display.set_caption(W_NAME)
        clock.tick(60)
    
    
    
        selecteurpage = 0
        run = 1
    
        while run:
            for event in pygame.event.get():
                if event.type == QUIT:
                    run = 0
                if selecteurpage == 0:
                    initGame(mySurface, screen)
    
    
    
    main()



    • Partager sur Facebook
    • Partager sur Twitter
      10 janvier 2018 à 22:09:24

      Bonjour bonsoir,

      Alors j'ai peut être une idée, selon moi il faudrait qu'il y ait un moment donné un boucle (je ne sais pas si tu en a mise une mais que tu ne la pas montrer ici) le problème je pense c'est que lorsque tu appelle ta fonction, il faut que pile a ce moment la il y est un clic ! Alors que si tu utilise une boucle et que cette boucle ne sera False que après avoir eu un clic cela marcherais a tout les coups.

      J’espère que je t'ais mis sur la vois xD je suis pas bien claire et le problème ne vient peut être pas de la je suis pas bien sur

      • Partager sur Facebook
      • Partager sur Twitter
        11 janvier 2018 à 2:08:20

        Salut,

        Premièrement, je sais qu'il y a une erreur aux lignes #134-135. Puisque votre condition devrait être après la boucle FOR.

        PS: De plus, le clock.tick(60), devrait être dans la boucle WHILE.

        Deuxièmement, vous avez pas besoin d'une surface externe au screen. C'est de trop. Puisque n'oubliez pas que vous êtes dans la boucle.

        Donc comme ceci:

        def main():
            screen = pygame.display.set_mode(W_SIZE)
            pygame.display.set_caption(W_NAME)
         
            selecteurpage = 0
            run = 1
         
            while run:
                for event in pygame.event.get():
                    if event.type == QUIT:
                        run = 0
                    if event.type == KEYDOWN:
                        if event.key == K_ESCAPE:
                            run = 0
                            
                if selecteurpage == 0: ## Pas dans la boucle FOR
                    initGame(screen)
        
                pygame.display.flip()
                clock.tick(60)
        
            pygame.quit()
        

        Il doit être après la boucle FOR, pas à l'intérieur.

        Troisièmement, vous avez besoin que d'un seul pygame.display.flip() (Dans la boucle WHILE).

        Donc, enlever tous les autres... ils sont inutiles

        Exemple:

        def displayTxt(screen, text, color, x, y, fontWeight,tipo):
            font = pygame.font.Font(tipo, fontWeight)
            display = font.render(text, True, color)
            position = display.get_rect()
            position.topleft = (x, y)
            screen.blit(display, position )

        J'ai aussi enlevé la surface qui était de trop.

        Quatrièmement, puisque votre fonction initGame() est dans la boucle, vous avez pas besoin de ré-écrire les displayTxt, dans les conditions de click()....

        Ce qui devrait ressembler à ceci:

        def initGame(screen):
            global nbplayer
            global nbrows
            global nbcolumns
        
            screen.fill((0,0,0))
            
            displayTxt(screen, "select number of player", WHITE, 100, 100, 48,"HACKED.ttf")
            displayTxt(screen, "Select number of rows", WHITE, 100, 250, 48,"HACKED.ttf")
            displayTxt(screen, "select number of columns", WHITE, 100, 400, 48,"HACKED.ttf")
            displayTxt(screen, "START", ROUGE, 550, 600, 70,"HACKED.ttf")
            #selecteur ligne 1
            displayTxt(screen, "<", WHITE, 800, 100, 70,"HACKED.ttf")
            displayTxt(screen, str(nbplayer), WHITE, 900, 100, 70,"arial.ttf")
            displayTxt(screen, ">", WHITE, 1000, 100, 70,"HACKED.ttf")
            # selecteur ligne 2
            displayTxt(screen, "<", WHITE, 800, 250, 70,"HACKED.ttf")
            displayTxt(screen, str(nbrows), WHITE, 900, 250, 70,"arial.ttf")
            displayTxt(screen, ">", WHITE, 1000, 250, 70,"HACKED.ttf")
            # selecteur ligne 3
            displayTxt(screen, "<", WHITE, 800, 400, 70,"HACKED.ttf")
            displayTxt(screen, str(nbcolumns), WHITE, 900, 400, 70,"arial.ttf")
            displayTxt(screen, ">", WHITE, 1000, 400, 70,"HACKED.ttf")
         
            if click(800,100,50,50 ) == 1 and nbplayer > 2:
                nbplayer -= 1
            if click(1000,100,50,50 ) == 1 and nbplayer < 8:
                nbplayer += 1
            if click(800,250,50,50 ) == 1 and nbrows > 1:
                nbrows -= 1
            if click(1000,250,50,50 ) == 1:
                nbrows += 1
            if click(800,400,50,50 ) == 1 and nbcolumns > 1:
                nbcolumns -= 1
            if click(1000,400,50,50 ) == 1:
                nbcolumns += 1


        Ensuite, j'essaye de comprendre, pourquoi cela ne fonctionne pas.  C'est comme s'il détectait uniquement la première condition du click. Donc, uniquement la ligne #74. Tous les autres sont ignorés. Je vois que c'est à cause que vous êtes dans la boucle WHILE. (Comme dit AmoriGris).

        Puisque, si je met ce print() dans votre click(), je vois que c'est uniquement le premier click(), qui fonctionne... tous les autres sont ignorés.

        print(mouseX,mouseY, (x, y, x+width, y+height))

        Sauf que, si je remplace votre fonction click(), par ceci: (FONCTIONNEL)

        def click(x,y,width,height):
            mouse = pygame.mouse.get_pressed()
            if mouse[0]:
                mouseX, mouseY = pygame.mouse.get_pos()
                print(mouseX,mouseY, (x, y, x+width, y+height))
                if mouseX > x and mouseX < x + width and mouseY > y and mouseY < y + height:
                    return True
            return False

        Tout fonctionne à merveille, sauf que c'est trop rapide. (Les cliques se font trop rapidement). MAIS TOUT FONCTIONNE....

        EN BONUS:

        J'ai essayé de retourner les rectangle de vos fonts, et de détecter les collisions entre les rectangle et la position de la souris, mais cela ne fonctionne toujours pas. Les positions des rectangles ne change pas..

        En utilisant rect.collidepoint(x, y)

        Exemple:

        def displayTxt(screen, text, color, x, y, fontWeight,tipo):
            font = pygame.font.Font(tipo, fontWeight)
            display = font.render(text, True, color)
            position = display.get_rect()
            position.topleft = (x, y)
            screen.blit(display, position )
            return position
        
        def click(rect):
            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                    mouseX = event.pos[0]
                    mouseY = event.pos[1]
                    print(mouseX, mouseY, rect)
                    if rect.collidepoint(mouseX, mouseY):
                        return True
                    else:
                        return False
        
        def initGame(screen):
            global nbplayer
            global nbrows
            global nbcolumns
        
            screen.fill((0, 0, 0))
            
            displayTxt(screen, "select number of player",
                       WHITE, 100, 100, 48,"HACKED.ttf")
            displayTxt(screen, "Select number of rows",
                       WHITE, 100, 250, 48,"HACKED.ttf")
            displayTxt(screen, "select number of columns",
                       WHITE, 100, 400, 48,"HACKED.ttf")
            displayTxt(screen, "START", ROUGE, 550, 600, 70,"HACKED.ttf")
            
            #selecteur ligne 1
            aa = displayTxt(screen, "<", WHITE, 800, 100, 70,"HACKED.ttf")
            displayTxt(screen, str(nbplayer), WHITE, 900, 100, 70,"arial.ttf")
            bb = displayTxt(screen, ">", WHITE, 1000, 100, 70,"HACKED.ttf")
            # selecteur ligne 2
            cc = displayTxt(screen, "<", WHITE, 800, 250, 70,"HACKED.ttf")
            displayTxt(screen, str(nbrows), WHITE, 900, 250, 70,"arial.ttf")
            dd = displayTxt(screen, ">", WHITE, 1000, 250, 70,"HACKED.ttf")
            # selecteur ligne 3
            ee = displayTxt(screen, "<", WHITE, 800, 400, 70,"HACKED.ttf")
            displayTxt(screen, str(nbcolumns), WHITE, 900, 400, 70,"arial.ttf")
            ff = displayTxt(screen, ">", WHITE, 1000, 400, 70,"HACKED.ttf")
            
            if click(aa) and nbplayer > 2:
                print('clicka')
                nbplayer -= 1
            elif click(bb) and nbplayer < 8:
                print('clickb')
                nbplayer += 1
            if click(cc) and nbrows > 1:
                print('clickc')
                nbrows -= 1
            elif click(dd):
                print('clickd')
                nbrows += 1
            if click(ee) and nbcolumns > 1:
                 print('clicke')
                 nbcolumns -= 1
            elif click(ff):
                print('clickf')
                nbcolumns += 1

        J'essaye de comprendre ce qui cloche.. les boîtes des rectangles ne changent pas. Donc rien fonctionne....


        En conclusion, c'est vraiment parce que vous êtes dans la boucle. Vous devriez trouver un autre moyen..

        • Soit que vous prenez la fonction click(), que j'ai écris. (Mais c'est très rapide).
        • Soit, vous trouvez un autre moyen, je sais pas trop... :( les rectangles (rect.collidepoint(x,y)) semblait un bon moyen, mais cela ne fonctionne pas..

        J'espère que je vous ai pas trop mélangé. (On peut pas dire que j'ai pas essayé :-°)

        N'hésitez pas pour les questions.

        Bonne chance

        A+

        -
        Edité par nolimitech 11 janvier 2018 à 2:09:02

        • Partager sur Facebook
        • Partager sur Twitter
          16 janvier 2018 à 23:02:23

          Bonjour, 

          Deja merci a tous,

          j'ai regllé le problème le lendemain mais je n'ai pas eu le temps de me reconnecter ^^

          alors explication :

          a chaque appelle de ma fonction click je recherche si une touche est pressé pour faire je parcoure tout les evenement (for event in ...)

          ce qui est trés mal optimisé et qui explique pourquoi le code ne fonctionnait pas :)

          donc la solution :

          def click(mouseX,mouseY,x,y,width,height):
          
              if mouseX > x and mouseX < x + width and mouseY > y and mouseY < y + height:
                  return True
              else:
                  return False
          
          
          def initGame(mySurface, screen):
          
              global nbplayer
              global nbrows
              global nbcolumns
              global run
              global selecteurpage
          
          
          
              displayTxt(mySurface, screen, "select number of player", WHITE, 100, 100, 48,"HACKED.ttf")
              displayTxt(mySurface, screen, "Select number of rows", WHITE, 100, 250, 48,"HACKED.ttf")
              displayTxt(mySurface, screen, "select number of columns", WHITE, 100, 400, 48,"HACKED.ttf")
              displayTxt(mySurface, screen, "START", ROUGE, 550, 600, 70,"HACKED.ttf")
              #selecteur ligne 1
              displayTxt(mySurface, screen, "<", WHITE, 800, 100, 70,"HACKED.ttf")
              displayTxt(mySurface, screen, str(nbplayer), WHITE, 900, 100, 70,"arial.ttf")
              displayTxt(mySurface, screen, ">", WHITE, 1000, 100, 70,"HACKED.ttf")
              # selecteur ligne 2
              displayTxt(mySurface, screen, "<", WHITE, 800, 250, 70,"HACKED.ttf")
              displayTxt(mySurface, screen, str(nbrows), WHITE, 900, 250, 70,"arial.ttf")
              displayTxt(mySurface, screen, ">", WHITE, 1000, 250, 70,"HACKED.ttf")
              # selecteur ligne 3
              displayTxt(mySurface, screen, "<", WHITE, 800, 400, 70,"HACKED.ttf")
              displayTxt(mySurface, screen, str(nbcolumns), WHITE, 900, 400, 70,"arial.ttf")
              displayTxt(mySurface, screen, ">", WHITE, 1000, 400, 70,"HACKED.ttf")
              pygame.display.flip()
          
              for event in pygame.event.get():
                  if event.type == QUIT:
                      run = 0
                  if event.type == MOUSEBUTTONDOWN and event.button == 1:
                      mouseX = event.pos[0]
                      mouseY = event.pos[1]
                      if click(mouseX,mouseY,800,100,50,50 ) == 1 and nbplayer > 2:
                          nbplayer -= 1
                          mySurface.fill((0, 0, 0))
                          displayTxt(mySurface, screen, str(nbplayer), WHITE, 900, 100, 70, "arial.ttf")
                          fond(mySurface)
                      if click(mouseX,mouseY,1000,100,50,50 ) == 1 and nbplayer < 8:
                          nbplayer += 1
                          mySurface.fill((0, 0, 0))
                          displayTxt(mySurface, screen, str(nbplayer), WHITE, 900, 100, 70, "arial.ttf")
                          fond(mySurface)
                      if click(mouseX,mouseY,800,250,50,50 ) == 1 and nbrows > 3:
                          nbrows -= 1
                          mySurface.fill((0, 0, 0))
                          displayTxt(mySurface, screen, str(nbrows), WHITE, 900, 250, 70, "arial.ttf")
                          fond(mySurface)
                      if click(mouseX,mouseY,1000,250,50,50 ) == 1 and nbrows < 10:
                          nbrows += 1
                          mySurface.fill((0, 0, 0))
                          displayTxt(mySurface, screen, str(nbrows), WHITE, 900, 250, 70, "arial.ttf")
                          fond(mySurface)
                      if click(mouseX,mouseY,800,400,50,50 ) == 1 and nbcolumns > 3:
                          nbcolumns -= 1
                          mySurface.fill((0, 0, 0))
                          displayTxt(mySurface, screen, str(nbcolumns), WHITE, 900, 400, 70, "arial.ttf")
                          fond(mySurface)
                      if click(mouseX,mouseY,1000,400,50,50 ) == 1 and nbcolumns < 15:
                          nbcolumns += 1
                          mySurface.fill((0, 0, 0))
                          displayTxt(mySurface, screen, str(nbcolumns), WHITE, 900, 400, 70, "arial.ttf")
                          fond(mySurface)
                      if click(mouseX, mouseY, 550, 600, 150, 70) == 1 :
                          selecteurpage = 1
          
                      if event.type == QUIT:
                          run = 0

          je ne place plus qu'un seul for event in ... qui se trouve dans ma fonction et je l'enleve de la fonction click et le code marche parfaitement 

          nomilitech 

          pour les erreurs de clock et d'indentation je les ai corrigées depuis le code n'etait encore qu'ebauche a ce moment la ;)

          j'utilise plusieurs display.flip car mon code final affiche en realité beaucoup d'autre chose etape par etape et donc je dois a chaque etape affiché l'element et ne pas attendre qu'elles soientt toutes finis 

          ensuite si je ne reactualise pas mon texte a chaque changement il se reaffiche par dessus l'ancien voila pourquoi je dois reafficher mon texte a chaque clique

          voila histoire que tu comprenne mieux certains de mes choix en tout cas je te remercie enormément tu as l'air d'avoir pris de ton temps pour essayer de resoudre mon problème c'est super cool ! 

          -
          Edité par Cobalt7440-48-4 16 janvier 2018 à 23:12:57

          • Partager sur Facebook
          • Partager sur Twitter

          probleme interface graphique pygame

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown