[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Signals and Slots - Summerfield - what exactly is a signal?

Le 05/08/17 ? 16:28, veek a ?crit :
> 1. What exactly is a signal. In hardware, an interrupt can be viewed as a
> signal and the voltage on a pin will suddenly jump to +5V as an indicator
> that an interrupt has occurred. With Qt signals - if a widget-c++ code has
> to 'signal' an event - what does it do?
> As a consequence of not understanding the above..
> 2. How do you connect a single signal to multiple slots? Do the
> slots/methods get called one by one? or are they treated as independent
> threads and run on different cores?
You have to connect yours slots each by each.
Be care you can't know the order of the execution of foo and baz.
Any thread will be created for that, the binding will be executed into 
the main loop of your app.
But, if your signal is emitted from a thread, the slot will be executed 
into the main thread, this is a great advantage, your slot can interact 
safely with the graphics part of your app.
> 3. pg 130 of Summerfield
> class ZeroSpinBox(QObject):
>     def __init__(self, parent=None):
>        super(...blah initialize QObject with parent
>        self.connect(self, SIGNAL("valuedChanged(int)"), self.checkzero)
>     def checkzero(self):
>        if self.value() == 0:
>           self.emit(SIGNAL("atzero"), self.zeros)
> basically when SpinBox gets set to zero we emit 'atzero' and return a zeros
> counter.
> What i don't get is the valueChanged(int) bit.. he clearly defines an (int)
> being passed to checkzero so shouldn't the definition reflect the same?
> Mistake?
This is the old signal-slot methods, I encourage you to use the new (new 
but not recent) method
Like this:
from QtCore import pyqtSignal

class ZeroSpinBox(QObject):
    atZero = pyqtSignal(int)
    def __init__(self, parent=None):
       super(...blah initialize QObject with parent

    def checkzero(self, value):
       if not value:
          # maybe increment self.zeros ?
> A. additionally I did not understand short circuit signals where you can
> drop the (type1, type2) in the signature and just do
> SIGNAL("atzero")
> Is this doable ONLY in emit() or also in connect()??
I don't know, never used this construction of code.
> 4. pg 131 'any data can be passed as arguments to the emit method and they
> can be passed as Python objects'
> self.emit(SIGNAL("atzero"), 10, 20, 30) or
> self.emit(SIGNAL("atzero"), [10, 20, 30])
> does he mean i can pass a SINGLE OBJECT of any python type or does he mean
> multiple independent containers?
> (assuming the definition matches)
When you define your signal you can use any Python type
sig = pyqtSignal(int, float, str, str, ...)
> 5. He says 'a signal with one argument is a Qt signal or a non-short-circuit
> Python signal'
> So if I have a Qt widget in C++ and it emits a valueChanged(int) signal..
> okay he's going to have to convert our asm/x86 int to python-integer and
> then call the python-method that was mapped to 'valueChanged' with the
> python-integer argument OR the signal is being generated from Python code
> itself AND WILL be converted to C++ datatype - huh???? why??
The wrapper use simply the CPython "PyLong_AsLong" or "PyUnicode_FromString"
or "Py_BuildValue" or other and you get always a Python object.
> I'm guessing there's some dispatch code that maintains a mapping table?? SO
> why can't it differentiate between inhouse python widget and Qt-c++ widget??
> 6. "If we use the SIGNAL() function with a signalSignature (a possibly empty
> parenthesized list of comma-separated PyQt types)..."??
> how can it be an empty () list..?? If there's a list it's no longer empty..
> 7. What exactly is a Python signal vs a Qt signal originating from a C++-
> asm-widget?? PyQt is a wrapper around C++Qt so.. where are the python
> widgets??
> 8.
> class TaxRate(QObject):
>    def __init__(self):
>      super(TaxRate, self).__init__()
>      self.__rate = 17.5
>    def rate(self):
>      return self.__rate
>    def setRate(self, rate):
>      if rate != self.__rate:
>         self.__rate = rate
>         self.emit(SIGNAL("rateChanged"), self.__rate)
> def rateChanged(value):
> 	print "TaxRate changed to %.2f%%" % value
> vat = TaxRate()
> vat.connect(vat, SIGNAL("rateChanged"), rateChanged)
> vat.setRate(17.5) # No change will occur (new rate is the same)
> vat.setRate(8.5) # A change will occur (new rate is different)
> Isn't this a mistake? self.connect( should be:
> vat.connect(vat, SIGNAL("rateChanged"), rate)
Again, use the new syntaxe (new but not recent) it's more clear.