Re: PyQT - Signals and Slots?
On 10/10/2016 07:32 AM, Veek M wrote: > Whaaa...t?? Could someone explain what exactly is his grand design > besides being awfully circuitous? So he has some other Form thingy.. and > in that he sets up another mapping from ZeroSpinBox.atzero --> > ZeroSpinBox.announce where's announce and atzero defined? In your example code, "atzero" is implicitly defined as a signal in the connect() call. Under the hood in Qt, signals are all dispatched by strings when you emit() the signal. PyQt does allow you to define signals in a more pythonic way using class variables: class Foo(QWidget): atzero = SIGNAL( signature ) The signature can be a list of python types, or strings describing the C++ types. This is where the C++ nature of Qt leaks into PyQt. In C++ since the moc compiler takes C++ code and C++ type names and generates a meta-class that defines signals in terms of strings (moc does basic compile-time type checking), in Python we also have to provide signatures in strings also if we need something more than core python types (int, bool, etc). This signature helps PyQt (well Qt really) marshal the types properly when the signal's callback is called. But yes the example is convoluted and circuitous. I think it's just to demonstrate how signals and slots work, though. That's what the comments make clear. This isn't how you'd implement a real widget with customized behavior. In general I don't think widgets normally want to catch their own signals. There are other mechanisms for that. Usually you subclass the widget and then override the appropriate *Event() method. For example, to do something special on value changes I believe you'd subclass QSpinBox and override the changeEvent() method. Inside that you would get your value, do your logic, and potentially emit a custom signal. And of course calling the parent changeEvent() to propagate the event through to the parent class. -- https://mail.python.org/mailman/listinfo/python-list
Re: PyQT - Signals and Slots?
Mark Summerfield wrote: > > The ZeroSpinBox is a tiny example designed to show how the signal/slot > mechanism works. It is just a QSpinBox with the addition of > remembering how many times (all the) ZeroSpinBox(es) have had a 0 > value. > > Nowadays the connections would be made with a new improved syntax: > > self.connect(self, SIGNAL("valueChanged(int)"), self.checkzero) # OLD > self.valueChanged.connect(self.checkzero) # NEW > # or > self.valueChanged[int].connect(self.checkzero) # NEW > > Similarly the emit: > self.emit(SIGNAL("atzero"), self.zeros) # OLD > self.atzero.emit(self.zeros) # NEW > > What's happening inside ZeroSpinBox? Whenever its value is set to 0 it > calls its own checkzero() method, and this in turn emits an atzero > signal with the number of zeros so far. Why does it do this? Just to > show the mechanism. It doesn't matter whether you connect a widget to > itself (unusual but done here), or to another widget (the norm). > > See the book's website https://www.qtrac.eu/pyqtbook.html > for all the source code including some updated with the new syntax. > (But the book is old, so even the Python 3.1 examples aren't as > Pythonic as they would be written in Python 3.4+.) ah - okay, so i was on the right track - thanks :) cool that you hang out here :) -- https://mail.python.org/mailman/listinfo/python-list
Re: PyQT - Signals and Slots?
The ZeroSpinBox is a tiny example designed to show how the signal/slot mechanism works. It is just a QSpinBox with the addition of remembering how many times (all the) ZeroSpinBox(es) have had a 0 value. Nowadays the connections would be made with a new improved syntax: self.connect(self, SIGNAL("valueChanged(int)"), self.checkzero) # OLD self.valueChanged.connect(self.checkzero) # NEW # or self.valueChanged[int].connect(self.checkzero) # NEW Similarly the emit: self.emit(SIGNAL("atzero"), self.zeros) # OLD self.atzero.emit(self.zeros) # NEW What's happening inside ZeroSpinBox? Whenever its value is set to 0 it calls its own checkzero() method, and this in turn emits an atzero signal with the number of zeros so far. Why does it do this? Just to show the mechanism. It doesn't matter whether you connect a widget to itself (unusual but done here), or to another widget (the norm). See the book's website https://www.qtrac.eu/pyqtbook.html for all the source code including some updated with the new syntax. (But the book is old, so even the Python 3.1 examples aren't as Pythonic as they would be written in Python 3.4+.) -- https://mail.python.org/mailman/listinfo/python-list
PyQT - Signals and Slots?
I'm reading Rapid GUI Programming - Mark Summerfield with Python and QT pg 131. Basically the mechanism is an event table which maps a 'signal' to a 'function/slot' -correct? self.connect(dial, SIGNAL("valueChanged(int)"), spinbox.setValue) Here, dial.valueChanged -> spinbox.setValue s.connect(w, SIGNAL("signalSignature"), functionName) s.connect(w, SIGNAL("signalSignature"), instance.methodName) s.connect(w, SIGNAL("signalSignature"), instance, SLOT("slotSignature")) Here, w.signalSignature -> functionName -> instance.methodName -> instance.slotSignature If signalSignature is a C++ implemented thingy then we got to pass type info as part of the mapping so "signalSignature(int, float, const char *). PyQT signals are any type and any number of args.. If the Slot-function is implemented in C++ it's better to use the SLOT() mechanism: self.connect(dial, SIGNAL("valueChanged(int)"), spinbox, SLOT("setValue(int)")) Here, we are mapping dial.valueChanged(int) --> spinbox.setValue(int) The part i found tricky was this: class ZeroSpinBox(QSpinBox): zeros = 0 def __init__(self, parent=None): super(ZeroSpinBox, self).__init__(parent) self.connect(self, SIGNAL("valueChanged(int)"), self.checkzero) def checkzero(self): if self.value() == 0: self.zeros += 1 self.emit(SIGNAL("atzero"), self.zeros) ZeroSpinBox.valueChanged -> ZeroSpinBox.checkzero? Why is he mapping back to himself? Shouldn't it be widget-to-widget? Then he raises a signal 'atzero' with one arg - the lack of a atzero() implies it's a 'short-circuit' signal so self.zeroes is a python data type. And in the book he says: ### Here is how we connect to the signal in the form’s __init__() method: zerospinbox = ZeroSpinBox() ... self.connect(zerospinbox, SIGNAL("atzero"), self.announce) Again, we must not use parentheses because it is a short-circuit signal. And for completeness, here is the slot it connects to in the form: def announce(self, zeros): print "ZeroSpinBox has been at zero %d times" % zeros ### Whaaa...t?? Could someone explain what exactly is his grand design besides being awfully circuitous? So he has some other Form thingy.. and in that he sets up another mapping from ZeroSpinBox.atzero --> ZeroSpinBox.announce where's announce and atzero defined? -- https://mail.python.org/mailman/listinfo/python-list