0

I have a scroll area which has N buttons in it. I need to know which button was pressed. How can I detect it?
My code:

from PyQt5.QtWidgets import QDialog
from PyQt5.QtWidgets import QApplication, QScrollArea,QHBoxLayout, QGroupBox, QPushButton, QFormLayout
import sys

class MainWindow(QDialog):
    def __init__(self):
        super().__init__()
        self.setGeometry(10, 20, 500, 500)
        layout = QHBoxLayout(self)
        self.formLayout1 = QFormLayout()
        self.groupBox1 = QGroupBox("test")

        for i in range(20):
            self.formLayout1.insertRow(0, QPushButton(str(i)))

        self.groupBox1.setLayout(self.formLayout1)
        scroll1 = QScrollArea()
        scroll1.setWidget(self.groupBox1)
        layout.addWidget(scroll1)
        self.show()

if __name__ == '__main__':
    App = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(App.exec())
  • 1
    change `self.formLayout1.insertRow(0, QPushButton(str(i)))` to `self.formLayout1.insertRow(0, QPushButton(str(i), clicked=lambda _, n=i: print(f'QPushButton_{n}')))` – S. Nick Feb 05 '20 at 13:05

1 Answers1

0

You could install an event filter to all your buttons, give them an object name and then check it by source:

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5 import *
import sys

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setGeometry(10, 20, 500, 500)
        layout = QHBoxLayout(self)
        self.formLayout1 = QFormLayout()
        self.groupBox1 = QGroupBox("test")

        for i in range(20):
            new_button = QPushButton(str(i), self)
            button_name='button_number_{}'.format(i)
            new_button.setObjectName(button_name)
            new_button.installEventFilter(self)
            self.formLayout1.insertRow(0,new_button)

        self.groupBox1.setLayout(self.formLayout1)
        scroll1 = QScrollArea()
        scroll1.setWidget(self.groupBox1)
        layout.addWidget(scroll1)
        self.show()


    def eventFilter(self, source, event):
            if event.type() == QtCore.QEvent.MouseButtonPress:
                print(source.objectName())
            return super().eventFilter(source, event)


if __name__ == '__main__':
    App = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(App.exec())
Felix Dumitrascu
  • 115
  • 1
  • 10
  • 1
    It's worth noticing that buttons usually are considered "*clicked*" when the mouse is released within their area, not when *any* mouse button is pressed upon them. – musicamante Feb 05 '20 at 17:34
  • I see, what event would that be? – Felix Dumitrascu Feb 05 '20 at 18:15
  • If you're going with the eventFilter (which is fine, since it's technically preferable than `QObject.sender()`), I'd check the event against the following conditions: `event.type() == QtCore.QEvent.MouseButtonRelease`, `event.button() == QtCore.Qt.LeftButton` and `event.pos() in source.rect()`. The only problem is that this doesn't take into account keyboard events that may cause the click anyway: the space bar if the button has focus, the return/enter keys if the button is set as default and no other widget reacts to them, or the button mnemonic (the "underscored" letter shortcut) is called. – musicamante Feb 05 '20 at 18:48