0

I am refactoring some code that uses old-style signals and slots, and one of the things it does is pass built-in signals as strings (e.g., signalName="clicked()") to another function that actually connects the signals and slots. E.g.:

self.connect(widget, QtCore.SIGNAL(signalName), slot)

This works fine. The problem is, converting to new-style signals and slots (where the signal is not passed as an argument) makes this more complicated. In new-style signal and slot, the above would be something like:

widget.[signalName].connect(slot)

Where [signalName] is something that works. :) I got a lot of things to not work without using eval:

widget.signalName.connect(slot) #AttributeError: widget object has no attribute 'signalName'

Based on a related post:

signalDict={}
signalDict["clicked"]=QtGui.QAbstractButton.clicked
widget.signalDict["clicked"].connect(slot) #AttributeError: widget object has no attribute 'signalDict'

Of course there is eval, which actually works:

fullCommand="widget." + signalName + ".connect(slot)"
eval(fullCommand)

But it uses eval, which is sort of frowned-upon. Is there a better way to translate such code into new-style signals and slots, without using eval?

Note the original code, that I am trying to translate into new-style signals and slots, is here: https://github.com/ghosert/VimProject/blob/master/pyqt/book_samples/chap06/imagechanger.pyw

It is from Chapter 6 of Summerfield's book on Qt programming.

Related question:

Passing Arguments with Newstyle signals in PyQT

Community
  • 1
  • 1
eric
  • 7,142
  • 12
  • 72
  • 138
  • Use `signalDict["clicked"] = QtGui.QAbstractButton.clicked` instead of `signalDict["clicked"]=QtGui.QAbstractButton.clicked()`. – dano Aug 05 '14 at 19:31

1 Answers1

6

How about this?

getattr(widget, signalName).connect(slot)

You may want to add a if hasattr(...) check beforehand to make sure the signal actually exists.

dano
  • 91,354
  • 19
  • 222
  • 219
  • It works!!! This also helps me appreciate that the dots aren't just for show: new-style connections are truly instance attributes :) – eric Aug 05 '14 at 19:38
  • 3
    @neuronet Cool! Also, new-style signals are actually **class** attributes, not instance attributes. If you try to define one as an instance attribute (`self.my_signal = ...`), you'll get an exception. I know because I've tried it before. :) – dano Aug 05 '14 at 19:42