Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using QSignalMapper

I tried to make a simple example to help understand how the concept of QSignalMapping works in PySide. I would like to dynamically create a series of buttons by iterating through a loop, and when the user pushes one of the buttons, I can activate a method that returns the appropriate label for the button that was pressed.

from PySide2 import QtWidgets,QtCore,QtGui

fruit_list = ["apples","oranges","pears"]

def fruit_button_event():
    print "this is the pressed button's label"

def main():
    for fruit in fruit_list:
        fruit_button = QtWidgets.QPushButton(fruit)
        fruit_button.clicked.connect(lambda:fruit_button_event())
main()
like image 356
winteralfs Avatar asked Dec 02 '25 22:12

winteralfs


1 Answers

In the next part I show an example how to use QSignalMapper:

from PySide2 import QtCore, QtWidgets


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        lay = QtWidgets.QVBoxLayout(self)

        fruit_list = ["apples","oranges","pears"]
        mapper =  QtCore.QSignalMapper(self)
        mapper.mapped[str].connect(self.fruit_button_event)

        for fruit in fruit_list:
            btn = QtWidgets.QPushButton(fruit)
            btn.clicked.connect(mapper.map)
            mapper.setMapping(btn, fruit)
            lay.addWidget(btn)

    @QtCore.Slot(str)
    def fruit_button_event(self, text):
        print("this is the pressed button's label", text)


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

Remember that from Qt 5.10 QSignalMapper is deprecated:

This class is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.


The same functionality in python can be obtained with functools.partial(...):

from PySide2 import QtCore, QtWidgets
from functools import partial


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        lay = QtWidgets.QVBoxLayout(self)

        fruit_list = ["apples","oranges","pears"]

        for fruit in fruit_list:
            btn = QtWidgets.QPushButton(fruit)
            btn.clicked.connect(partial(self.fruit_button_event, fruit))
            lay.addWidget(btn)

    @QtCore.Slot(str)
    def fruit_button_event(self, text):
        print("this is the pressed button's label", text)

Or with lambda:

btn.clicked.connect(lambda text=fruit: self.fruit_button_event(text))

Or QButtonGroup:

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        lay = QtWidgets.QVBoxLayout(self)

        fruit_list = ["apples","oranges","pears"]
        group = QtWidgets.QButtonGroup(self)
        group.buttonClicked.connect(self.OnButtonClicked)

        for fruit in fruit_list:
            btn = QtWidgets.QPushButton(fruit)
            group.addButton(btn)
            lay.addWidget(btn)

    @QtCore.Slot(QtWidgets.QAbstractButton)
    def OnButtonClicked(self, btn):
        print("this is the pressed button's label", btn.text())
like image 128
eyllanesc Avatar answered Dec 04 '25 13:12

eyllanesc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!