单击按钮导致多个函数调用

Posted

技术标签:

【中文标题】单击按钮导致多个函数调用【英文标题】:Click button cause multiple function calls 【发布时间】:2014-12-20 11:08:27 【问题描述】:

我开发了一个 python 程序。以下代码是我的程序。问题是当我单击调用 self.restartClicked() 方法的 self.ui.Restart_Btn 并单击 self.ui.B11 时,它调用方法 self.boardClicked() 两次(它应该只调用一次)。而且,在我点击self.ui.Restart_Btn 3rd,4th,5th,...次并点击self.ui.B11后,它会重复调用3,4,5,...次

我不知道我的程序会发生什么。

 from MainWin import Ui_MainWindow
 from WelcomDialog import Ui_Dialog

 class iCheckers(QMainWindow):
     def __init__(self, parent = None):
         super(iCheckers, self).__init__(parent)
         self.ui = Ui_MainWindow()
         self.ui.setupUi(self)

         # Attribute
         self.buttonArr = [  [self.ui.B11, self.ui.B12, self.ui.B13, self.ui.B14, self.ui.B15, self.ui.B16, self.ui.B17, self.ui.B18],
                             [self.ui.B21, self.ui.B22, self.ui.B23, self.ui.B24, self.ui.B25, self.ui.B26, self.ui.B27, self.ui.B28],
                             [self.ui.B31, self.ui.B32, self.ui.B33, self.ui.B34, self.ui.B35, self.ui.B36, self.ui.B37, self.ui.B38],
                             [self.ui.B41, self.ui.B42, self.ui.B43, self.ui.B44, self.ui.B45, self.ui.B46, self.ui.B47, self.ui.B48],
                             [self.ui.B51, self.ui.B52, self.ui.B53, self.ui.B54, self.ui.B55, self.ui.B56, self.ui.B57, self.ui.B58],
                             [self.ui.B61, self.ui.B62, self.ui.B63, self.ui.B64, self.ui.B65, self.ui.B66, self.ui.B67, self.ui.B68],
                             [self.ui.B71, self.ui.B72, self.ui.B73, self.ui.B74, self.ui.B75, self.ui.B76, self.ui.B77, self.ui.B78],
                             [self.ui.B81, self.ui.B82, self.ui.B83, self.ui.B84, self.ui.B85, self.ui.B86, self.ui.B87, self.ui.B88] ] 
         self.clicked_button = None
         self.turn = 0;  # 0 = Player, 1 = Computer
         self.computer_score = 0
         self.player_score = 0

         self.update_mainWin()
         self.init_board()
         self.init_dialog()
         self.show()   

     def init_dialog(self):
         self.dialog = QDialog()
         self.dialog.ui = Ui_Dialog()
         self.dialog.ui.setupUi(self.dialog)
         #self.dialog.show()

         self.dialog.ui.Player_first_Btn.clicked.connect(partial(self.start, 0))
         self.dialog.ui.Computer_first_Btn.clicked.connect(partial(self.start, 1))

     def start(self, firstPlayer):
         # firstPlayer = 0 >> Player Starts
         # firstPlayer = 1 >> Player Starts

         if firstPlayer == 0:
             self.turn = 0;
             print("Player Start!!")
         elif firstPlayer == 1:
             self.turn = 1;
             print("Computer Start!!")
         self.init_board()
         self.boardClicked(True)
         self.update_mainWin()
         self.dialog.hide()

     def init_board(self):
         self.board = [[0 for x in range(8)] for x in range(8)] 

         # Init Computer Piece
         for i in range(1,24,2):
             row = int(math.ceil( i/8 ))
             column = i%8
             if row % 2 == 1:
                 column -= 1
             self.board[row][column] = 2

         # Init Player Piece
         for i in range(41,64,2):
             row = int(math.ceil( i/8 ))
             column = i%8
             if row % 2 == 1:
                 column -= 1
             self.board[row][column] = 1

         # Init White Box
         for i in range(1,64,2):
            row = int(math.ceil( i/8 ))
            column = i%8
            if row % 2 == 0:
                column -= 1
            self.board[row][column] = -1


     def update_mainWin(self):
         # Update Turn
         self.updateTurn()

         # Initial Score Board
         self.updateScore()

         # Initial Restart Button
         self.ui.Restart_Btn.clicked.connect(self.restartClicked)

         # Initial Board Button
         self.initBoardBtn()

     def initBoardBtn(self):
         for i in range(0, 8):
             for j in range(0, 8):
                 self.buttonArr[i][j].clicked.connect(self.boardClicked)

     def boardClicked(self, reset = False):
         sender = self.sender()
         if self.clicked_button != None:
             button_name = self.clicked_button.objectName()
             button_nameArr = list(button_name)
             row = int(button_nameArr[1])-1;
             column = int(button_nameArr[2])-1;

             if self.board[row][column] == 0:
                 self.clicked_button.setStyleSheet("background-color: #383838;")
             elif self.board[row][column] == 1:
                 self.clicked_button.setStyleSheet("background-color: #383838;background-image: url(:/image/Red_Pieces.png);")
             elif self.board[row][column] == 2:
                 self.clicked_button.setStyleSheet("background-color: #383838;background-image: url(:/image/Black_Pieces.png);")
             elif self.board[row][column] == 3:
                 self.clicked_button.setStyleSheet("background-color: #383838;background-image: url(:/image/Red_King.png);")
             elif self.board[row][column] == 4:
                 self.clicked_button.setStyleSheet("background-color: #383838;background-image: url(:/image/Black_King.png);")

         if reset:
             self.clicked_button = None
             return

         self.clicked_button = sender
         button_name = self.clicked_button.objectName()
         button_nameArr = list(button_name)
         row = int(button_nameArr[1])-1;
         column = int(button_nameArr[2])-1;
         if self.board[row][column] == 0:
             self.clicked_button.setStyleSheet("background-color: #707070;")
         elif self.board[row][column] == 1:
             self.clicked_button.setStyleSheet("background-color: #707070;background-image: url(:/image/Red_Pieces.png);")
         elif self.board[row][column] == 2:
             self.clicked_button.setStyleSheet("background-color: #707070;background-image: url(:/image/Black_Pieces.png);")
         elif self.board[row][column] == 3:
             self.clicked_button.setStyleSheet("background-color: #707070;background-image: url(:/image/Red_King.png);")
         elif self.board[row][column] == 4:
             self.clicked_button.setStyleSheet("background-color: #707070;background-image: url(:/image/Black_King.png);")
         print("Board: " + sender.objectName());

     def restartClicked(self):
         print("Restart!")
         self.dialog.show()
         # self.init_dialog()

     def updateTurn(self):
         if self.turn == 0:
             self.ui.Turn_img.setStyleSheet("background-color: #909090;background-image: url(:/image/Red_Icon.png);")
         elif self.turn == 1:
             self.ui.Turn_img.setStyleSheet("background-color: #909090;background-image: url(:/image/Black_Icon.png);")

     def updateScore(self):
         self.ui.Computer_Score_label.setText(str(self.computer_score))
         self.ui.Player_Score_label.setText(str(self.player_score))

 if __name__ == '__main__':
     app = QApplication(sys.argv)
     window = iCheckers()
     sys.exit(app.exec_())  

【问题讨论】:

为什么不丢弃代码中不相关的部分来提供 SSCCE?另外,您确定在update_mainWin 中连接是个好主意吗?这听起来像是不时调用的方法,在这种情况下,您不应该这样连接。您要么断开连接,要么连接其余部分。 我刚刚看到我连接了多次。谢谢! @lpapp 好吧,如果问题通过答案解决了,请选择一个答案。 【参考方案1】:

原因比较直截了当,你误解了 Qt 中 connect 的工作原理。

您似乎在每次调用某些方法时将信号连接到插槽。这似乎与您(理所当然地)想要的相冲突。

您有解决此问题的方法和解决方案。

解决方法

使用唯一连接 (type=Qt.UniqueConnection)。

解决方案

将这些连接调用移至初始化阶段,或者至少在重新连接之前断开它们。前者是一般做法,但您的里程可能会有所不同。

【讨论】:

以上是关于单击按钮导致多个函数调用的主要内容,如果未能解决你的问题,请参考以下文章

单击按钮调用php函数

从代码中调用按钮单击的函数

通过单击按钮调用类函数

sweetAlert - 单击确认按钮时不调用函数

通过单击按钮从 HTML 调用 Angular2 组件函数

单击pyfltk中的按钮时如何调用函数