It looks like PySide (or, to be precise, Shiboken, the wrapper that allows Python access to Qt objects) is not able to directly connect to slots of objects directly created by Qt.
That seems a PySide bug: PyQt does not show that behavior, meaning that it's completely possible to achieve it.
A similar behavior sometimes happens with PyQt as well, but that's only in very specific cases: for protected methods of objects directly created by Qt. For example, trying to call initStyleOption()
of the default delegate of an item view raises a RuntimeError
("no access to protected functions or signals for objects not created from Python").
Still, that should not happen for public functions like setDefaultSectionSize()
is.
There are possible workarounds for that, though.
Using a lambda
As you already found out, you can just use a lambda. This will force PySide to connect to a python function instead of a Qt one: PySide always allows that kind of connection.
The drawback of this approach is the common problem with lambdas: if you directly use it as the connect()
argument, you completely lose any reference to it, so there is no way to specifically disconnect from that function, unless you disconnect all functions for that signal (or the whole object).
Lambdas can be referenced to, though:
header = my_view.verticalHeader()
header.setDefaultSectionSize_ = lambda s: header.setDefaultSectionSize(s)
spinbox2.valueChanged.connect(header.setDefaultSectionSize_)
With the code above, you can disconnect the function, since you now have a persistent reference to it.
Using a method
This is similar to the above, with the difference that we create a specific method to handle that, assuming that you keep a reference to the header (or, better, the view):
spinbox2.valueChanged.connect(self.updateMyViewSectionSize)
def updateMyViewSectionSize(self, size):
self.my_view.verticalHeader().setDefaultSectionSize(size)
It might be a bit more verbose, but it's also a better approach, since it consider the dynamic nature of verticalHeader()
and provides public access to a function you may need to call in other cases.
Explicitly set the header
This is a trick I normally use for the delegate issue mentioned above: whenever I need to get some info from the delegate based on its initStyleOption()
, I just create a new "dummy" delegate; since it has been created in Python, the problem doesn't occur anymore.
The same works for this case too: create and set a dummy header view.
my_view.setVerticalHeader(QHeaderView(Qt.Vertical, my_view))
Note that both the orientation and arguments are mandatory, and that the above should always be done as soon as possible (right after the table widget has been created).
I would still suggest you to file a report in the Qt bug tracker, hoping they will be able to fix it at least for PySide6 (PySide2 will probably be ignored, but you never know).