Python Pyside6, how to print name of object for debugging?

I’m doing a great tutorial learning how to make GUI programs with Pyside6: https://youtu.be/Z1N9JzNax2k . However, for debugging purposes I would like to show the name of the button object in the clicked signal/event.

This is my window class file I would import into the main program like main09a.py.

# File: main09class.py
from PySide6.QtWidgets import QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit

class Widget(QWidget): # Inherit QWidget
    def __init__(self):
        super().__init__() # This must go first before all else. 
        self.setWindowTitle("QLabel and QLineEdit")

        button1 = QPushButton("Grab data")
        button1.clicked.connect(self.button1_clicked)

        vlayout = QVBoxLayout()
        vlayout.addWidget(button)
        self.setLayout(vlayout)

    def button1_clicked(self):
        # I'd like to use a variable to print the object name "button1" here. 
        print("button1_clicked ")
        # print(self.name, "button1_clicked ") # Gives me an error "no attribute name"
   

Main program file:

"""QLabel and QLineEdit lecture.
File: main09a.py
"""

from PySide6.QtWidgets import QApplication
from main09class import Widget
import sys

app = QApplication(sys.argv)
widget = Widget() # Create class instance.
widget.show()

app.exec()

I could not find a property that would give me the name of the object, I was thinking of self.name or something like that.

Have any ideas how this could be done?

I appreciate your time. Thanks!

The cleanest way I can think of, is to make a button subclass, instances of which know their own names, and move button1_clicked on to that subclass from Widget (or give it a decorator that inserts the instance’s name into the click handler).

The issue with the current design is, button1_clicked could equally well be assigned as a click handler to button2 or button3 etc. I don’t know how to solve that without introspection (which as you’ve recently discovered can be expensive) or changing the way the click handler is defined, e.g. instead having a click handler factory method that gets the button’s name and makes that available to the returned click handler function as a variable in its parent scope.

The issue with the current design is, button1_clicked could equally well be assigned as a click handler to button2 or button3 etc.

Good points. This would probably not happen much in my programs but it’s possible. My button clicks, in a real program, would do very different things.

I’m no export at Python or Python GUI programming. Can I pass the name of the object to the button1_clicked function?

Like below. That would be one workaround.

    def button1_clicked(self, objname):
        # I'd like to use a variable to print the object name "button1" here. 
        print(objname, " clicked ")
        # print(self.name, "button1_clicked ") # Gives me an error "no attribute name"
   

I wonder if there’s a decorator for this. But you make good points.

When I need this, I reach for functools.partial:

btn.clicked.connect(functools.partial(callback, btn))
    def callback(self, btn):
        ...
1 Like