Search code examples
pythonpython-3.xpyqtpyqt5minesweeper

PyQt - get row and column of clicked button in grid


I am working on a minesweeper app in PyQt and ran into a problem, how to return a row and column of clicked button in a grid layout? Below is as minimal example as possible to demonstrate the problem. My code always returns the last row and column and I dont know how to fix it. Other things I tried was using 2D list, but still didnt manage to get it working.

from PyQt5 import QtWidgets, QtCore, QtGui
import sys


class ApplicationWindow(QtWidgets.QWidget):

def __init__(self, size):
    super(ApplicationWindow, self).__init__()
    self.setGeometry(0, 0, 600, 400)
    self.setWindowTitle('MineSweeper')
    self.size = size
    self.grid_layout = QtWidgets.QGridLayout()   
    self.grid_layout.setSpacing(0)
    self.create_grid(self.size)
    self.setLayout(self.grid_layout)

def create_grid(self):        
    for row in range(self.size):
        for col in range(self.size):
            grid_button = QtWidgets.QPushButton()
            grid_button.clicked.connect(lambda: self.tell_me(row, col))
            grid_button.setFixedSize(30, 30)
            grid_button.setStyleSheet('background-color : rgba(0, 0, 0, 100); border :1px solid rgba(0, 0, 0, 150)')
            self.grid_layout.addWidget(grid_button, row, col)

def tell_me(self, row, col):
    print(row, col)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = ApplicationWindow(10)
    window.show()
    sys.exit(app.exec())

UPDATE: So I managed to return the correct number of column, but I keep getting False for the number of row, when I changed the lambda function

grid_button.clicked.connect(lambda r=row, c=col: self.tell_me(r, c))

Solution

  • The clicked signal always has a bool argument for the checked state, you must consider that in the lambda too, because it's what is used for the first argument.

    grid_button.clicked.connect(lambda _, r=row, c=col: self.tell_me(r, c))