单击按钮导致多个函数调用
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
)。
解决方案
将这些连接调用移至初始化阶段,或者至少在重新连接之前断开它们。前者是一般做法,但您的里程可能会有所不同。
【讨论】:
以上是关于单击按钮导致多个函数调用的主要内容,如果未能解决你的问题,请参考以下文章