The proper use of QSignalMapper

borntonetwork borntonetwork at gmail.com
Sat Jan 20 16:03:12 CET 2007


David, thanks for your help. Unfortunately, all attempts of making this
solution work have failed. I would be interested to know if anyone has
used QSignalMapper successfully in a similar situation. For any
interested, I worked around the problem using a closure, which seems a
bit cleaner from a coding point of view, although I don't have any idea
if it is more efficient or not:

    def makeHandler(self, idx):
        def handler(state):
            print 'The state is:', str(state), 'for checkbox object',
                    str(idx)
        return handler

Each iteration then created a new function based on the closure:

        self.handlers = []
        for idx in range(1, maxIngredients+1):
            wName = 'chkProductIngredientsDelete_'+str(idx)
            w = self.__dict__[wName]
            self.handlers.append(self.makeHandler(idx - 1))
            self.window.connect(w, QtCore.SIGNAL("stateChanged(int)"),
                    self.handlers[idx - 1])

So now the output when each checkbox is clicked is something like this:

The state is: 2 for checkbox object 0
The state is: 2 for checkbox object 1
...



David Boddie wrote:
> borntonetwork wrote:
> > Thanks, David, for you help.
> >
> > When I change the slot function to what you show in your second
> > example, I get the same results: nothing.
>
> This may be due to something I missed in your code. When you
> connect the signal from the signal mapper to your class, you
> need to specify the signal as a C++ signature as well:
>
>         self.connect(self.signalMapper, QtCore.SIGNAL(
>              "mapped(int)"),
>              self.deleteProductIngredient)
>
> The second example should now work.
>
> Looking at the first example, which uses SLOT() rather than specifying
> a Python method, the following might be due to the way you call
> connect, though it is surprising:
>
> > When I change it to what you
> > have in your first example, I get the following:
> >
> > Object::connect: No such slot QApplication::map()
> > Object::connect:  (sender name:   'chkProductIngredientsDelete_1')
> > Object::connect:  (receiver name: 'main.py')
>
> [...]
>
> It looks like you should try something like this:
>
>              self.connect(w, QtCore.SIGNAL("stateChanged(int)"),
>                   self.signalMapper,
>                   QtCore.SLOT("map()"))
>
> I can't understand why calling self.app.connect() would cause the
> connection to be attempted between self.signalMapper and self.app.
>
> Maybe someone on the PyQt/PyKDE mailing list would be able to
> explain the behaviour you're seeing:
> 
>   http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
> 
> David




More information about the Python-list mailing list