Thanks for replies. Let me summarize if I understood all this correctly.

Qt/PySide doesn't allow to pass additional parameters to signal
handlers if signal signature doesn't have them. For example, it is
impossible to pass `param` to choose_color() function in the following
snippet (so, the snippet is invalid):

 button = QPushButton('Choose Color')
 def choose_color(param):
   pass
 button.clicked.connect(choose_color)


To solve this problem:
1. Subclass button and move choose_color() to its method, so that it
can access all properties it requires
    * this seems logical, because button is used to select color, but
the problem appears again when you need to specify which component you
need to paint - a workaround there will be to define a property that
will hold the value
    * this makes code more complicated

 class MyButton(QPushButton):
   def __init__(self, *args, **kwargs):
     super(MyButton, self).__init__(self, *args, **kwargs)
     self.param = None
   def choose_color(self):
     pass
 button = MyButton('Choose Color')
 button.param = 'value'
 button.clicked.connect(choose_color)


2. Use QObject.sender()
http://www.pyside.org/docs/pyside/PySide/QtCore/QObject.html#PySide.QtCore.PySide.QtCore.QObject.sender
  * this fails when executed from a function:
        print QObject.sender()
     TypeError: descriptor 'sender' of 'PySide.QtCore.QObject' object
needs an argument
  * so it requires subclassing to make choose_color() a method
  * this allow to pass only reference to button itself, which can be
destroyed in the meanwhile according to the doc page


3. Create 'function closure' as suggested by Petr

 button = QPushButton('Choose Color')
 def choose_color():
   pass
 def choose_closure():
   choose_color(param)
 button.clicked.connect(choose_closure)

 * this one is surely confusing
 * as it opens a pandora box of whole lot of problems, because the
value of passed `param` will be its value at a time signal fires, not
at a time handler is defined


4. Define an object just for holding parameter
 class ParamHolder(object):
   def __init__(self, param):
     param = None
   def choose_color(self):
     pass
 button = MyButton('Choose Color')
 button.clicked.connect(ParamHolder(button).choose_color)

 * I guess that is the most generic solution to my problem


Does it worth to create an API helper to pass extra params to the
handler function in predictable way?

 def choose_color(param):   pass
button.clicked.connect_with_param(choose_color, button)
--
anatoly t.
_______________________________________________
PySide mailing list
[email protected]
http://lists.pyside.org/listinfo/pyside

Reply via email to