2017-10-07 25 views
1

Le code ci-dessous est écrit pour sélectionner les sièges dans un écran d'auditorium .. Comme je sélectionne le CheckBox j'ai besoin que le résultat soit affiché (Prix du billet) et aussi lorsque je tente de décocher la case le résultat doit être soustrait et affiché, au lieu de cela, il est tout simplement le résultat continue d'ajouter de 180 ...PyQt: Comment utiliser la méthode QCheckBox.isChecked()

import sys 
from PyQt4 import QtGui, QtCore, QtSql 

class SeatSel(QtGui.QWidget): 
    def __init__(self, parent=None): 
     super(SeatSel, self).__init__(parent) 
     self.a = {} 
     self.l = {} 
     self.l1 = QtGui.QLabel("\t\t  Screen", self) 
     self.l1.setStyleSheet("color : black") 
     self.l1.move(210,600) 
     self.l1.setAutoFillBackground(True) 
     self.l1.setMinimumWidth(700) 
     self.l3 = QtGui.QLabel("00    " ,self) 
     self.l3.setStyleSheet("color : white") 
     self.l3.move(1000, 500) 
     self.l3.setMaximumWidth(300) 
     self.display = QtGui.QLabel(self) 
     self.display.setStyleSheet("color : white") 
     self.display.move(800,800) 

     for i in range(14): 
      self.l[(i)] = QtGui.QLabel("%s" % chr(65+i), self) 
      self.l[(i)].setStyleSheet("color : white") 
      self.l[(i)].move(110, 103 + i * 32) 

     for i in range(26): 
      for j in range(14): 
       self.a[(i,j)] = QtGui.QCheckBox(self) 
       self.a[(i,j)].setMaximumSize(40,40) 
       self.a[(i,j)].setCheckable(True) 
       self.a[(i,j)].move(160+ (i-1) * 31,100 + j *32) 

    def seat(self, m_name, x, y): 
     self.l2 = QtGui.QLabel(m_name, self) 
     self.l2.move(x,y) 
     self.l2.setStyleSheet("color : white") 


class DeadPool(QtGui.QMainWindow): 
    def __init__(self, parent=None): 
     super(QtGui.QMainWindow, self).__init__(parent) 
     self.amount = 0 
     self.count = 0 
     self.setGeometry(50, 50, 1920, 1080) 
     self.showMaximized() 
     self.seat_sel("Conjuring", 640,40) 

    def full_screen(self): 
     if self.count == 0: 
      self.count=1 
      self.showFullScreen() 
     else : 
      self.count = 0 
      self.showNormal() 

    def exit(self): 
     sys.exit() 


    def seat_sel(self, m_name, x, y): 
     self.seat = SeatSel(self) 
     self.setWindowTitle("Select Seats") 
     self.setCentralWidget(self.seat) 
     self.seat.seat(m_name, x, y) 
     for i in range(26): 
      for j in range(14): 
       self.seat.a[(i,j)].stateChanged.connect(lambda : 
             self.seat_buttons(i, j)) 
     self.show() 

    def seat_buttons(self, i, j): 
     self.btn_toggle(self.seat.a[(i,j)]) 

    def btn_toggle(self, button): 
     if button.isChecked(): 
      self.amount -= 180 
      self.seat.l3.setNum(self.amount) 
     if not button.isChecked(): 
      self.amount += 180 
      self.seat.l3.setNum(self.amount) 

if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    w = DeadPool() 
    sys.exit(app.exec_()) 

Répondre

1

Il y a un problème dans la façon dont vous connectez le stateChanged signal à l'emplacement lambda. Lorsque vous connectez des signaux dans une boucle, les variables ne sont pas mises en cache, de sorte que chaque lambda se retrouve avec les mêmes valeurs (c'est-à-dire quelles que soient les valeurs finales des variables à la sortie de la boucle). Il existe plusieurs façons de résoudre ce problème. La première consiste à mettre en cache explicitement les valeurs à l'aide des arguments par défaut:

for i in range(26): 
     for j in range(14): 
      self.seat.a[(i,j)].stateChanged.connect(
       lambda state, i=i, j=j: self.seat_buttons(i, j)) 

Une autre façon consiste à utiliser functools.partial:

from functools import partial 
... 

    for i in range(26): 
     for j in range(14): 
      self.seat.a[(i,j)].stateChanged.connect(
       partial(self.seat_buttons, i, j)) 

Mais encore plus simple dans votre cas, serait d'utiliser sender(), qui renvoie tout objet envoyé le signal:

for i in range(26): 
     for j in range(14): 
      self.seat.a[(i,j)].stateChanged.connect(self.btn_toggle) 
...  

def btn_toggle(self, state): 
    button = self.sender() 
    if button.isChecked(): 
     self.amount += 180 
     self.seat.l3.setNum(self.amount) 
    else: 
     self.amount -= 180 
     self.seat.l3.setNum(self.amount) 

(PS: notez que j'ai troqué le +/- parce que je pense qu'ils sont dans le mauvais sens dans votre exemple de code)