2005/9/9, Richard Dale <<a href="mailto:Richard_Dale@tipitina.demon.co.uk">Richard_Dale@tipitina.demon.co.uk</a>>:<div><span class="gmail_quote"></span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
You need some syntax to emit a signal:<br>emit foobar("hello", 5)</blockquote><div><br>
Ok. I was thinking in nothing special:<br>
>>> button.clicked()<br>
or<br>
>>> button.signal_clicked()<br>
<br>
But we can do something like:<br>
>>> button.emit('clicked()', (,) )<br>
Or<br>
>>> button.emit('clicked(bool)', (True,) )<br>
 </div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">So emit() would be a method which doesn't actually do anything, then foobar()<br>
might actually map onto a common method for all signals. You then look at the<br>current stackframe to find the name of the actual ruby method, then look up<br>it's id number via the QMetaObject.</blockquote><div><br>
Hmm, don't like this part. I think this is not safe, I say, we can have
functions pointing to functions (adapters) and it could mess up. Well,
I just think "button.emit" is more simple. <br>
<br>
</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Yes, it's better to have exactly the same syntax for using both python and C++<br>
signals.</blockquote><div><br>
It is not just about sintax. PYSIGNALs don't exist in C++ world. This
means you can't embedded it back in C++. In python-qt4 it is already
possible, with no headaches.<br>
 </div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Oops, typo make that just 1000 classes.</blockquote><div><br>
Sure, but is still a lot o classes. I am thinking about it. But this
sounds to me we must work on a parser, or to tweak a existing parser,
to be able to read the QObjects and understand those macros like
Q_PROPERTY, Q_INTERFACE, Q_INFO.<br>
<br>
I mean, in Python things are a little different:<br>
C++:<br>
button->setVisible(true);<br>
std::cout<< button->isVisible() << std::endl;<br>
<br>
Python:<br>
>>> button.visible = True<br>
>>> print button.visible <br>
True<br>
<br>
Right now, it is only possible because I say to Boost.Python that
"setVisible" and "isVisible" are setter and getter of a "visible" a
property. "Dumb" scripts will never discover it. That's what I say
about being more Pythonic. Well part of the hole story.<br>
</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">That sounds interesting. I'm pretty sure your shouldn't have to intervene to<br>
make the binding more pythonic</blockquote><div><br>
Not just more Pythonic, but more interesting. For example, there is no
point in wrapping the QString class. Python have a "unicode" and "str"
class that work pretty well. Instead of wrapping everything, we write
custom converters that do it transparently:<br>
<br>
In old SIP/PyQt:<br>
>>> button = QPushButton(u'Ok', None) # entered a unicode<br>
>>> button.text() # this is a QString, no unicode.<br>
<__main__.qt.QString object at 0xf7f7b630><br>
<br>
In new python-qt4:<br>
>>> button = QPushButton(u'Ok', None)<br>
>>> button.text # a propery, no need to ()<br>
u'Eric' # a real genuine Python unicode object, ready for i18n <br>
 </div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Yes, it sounds worth experimenting with.</blockquote><div><br>
Yes, but I think we (binders) must work together in a single parse of a
QObject child class header. That would be good for everyone. Maybe the
Smoke project<br>
 </div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Smoke is a language independent auto generated library used by the QtRuby and<br>
PerlQt bindings at the moment. </blockquote><div><br>
Sounds tasty. Where can I find Smoke for Qt4?<br>
</div><br>
<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">It could be used by java, C# and possibly<br>python too. At the moment its main problem is that it's too monolithic, and
<br>everything is all in one big library. </blockquote><div><br>
Java and C# are not "scripting" languages. I see no point porting Qt to
those (no offenses). Well, maybe the guys who write the bindings have
some good points, but I just can't see it. Well, if I want static
typing I can continue with good old C++. <br>
<br>
I think new Qt4/Smoke will be very interesting. Maybe the code I wrote for python-qt4 help in something.<br>
 <br>
</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">It stands for 'Scripting Meta Object<br>Kompiler Engine', and is a sort of 'moc on steroids' - it adds an
<br>introspection layer for the complete api, and a language independent way of<br>invoking methods dynamically, or virtual methods callbacks.</blockquote><div><br>
Nice. <br>
<br>
</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Yes, that's the idea. Otherwise, you need a large library for each language,<br>instead of a single wrapper library like Smoke, with a smaller 'adaptor'
<br>layer for each language. </blockquote><div><br>
Hmm, should think more about it. Need to learn more.<br>
 <br>
</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">A future version of Smoke could use the Qt4 moc<br>format, but include ordinary methods as well as signals and slots, along with
<br>a way of adding virtual method callbacks so you can override them in the<br>scripting language.<br></blockquote></div><br>
That's easy to do with Boost.Python. The problem is find a way of doing it for all "script" languages.<br>
<br>
I just not agree with that part of "turn all ordinary method signals
and slots". If you think better, it will "polute" the interface of the
object. Beside this, signals and slots can be overloaded, so if you
want to use it with embedded C++ or with other binding, you should do
combinatorial job with the args!<br>
<br>
I mean "clicked(bool)" and "clicked()" stantds for the same slot. But
this is just a single C++ method. Now imagine how do you expose
"my_custom_method(self, begin, end, *args, **kw)"? There is no type
information here.<br>
<br>
My current idea (I may change it) is:<br>
<br>
- If we want to expose a signal (so even QtDesigner can read it), we must say it, and which types. Ex:<br>
class MyWidget(QObject):<br>
   @signal('int, int')  # this is a Python decorator. You can do it the old way, too.<br>
   def textChanged(begin, end):<br>
      ...<br>
# valid for the class<br>
<br>
- If we want to expose a slot (same as above):<br>
   @slot('QString')<br>

   def setHeader(text):<br>
      ...<br>
# valid for the class<br>
<br>
- If we want to connect any kind of signal to a QObject method, we
promote that method to a slot, with the signature you used to connect
it:<br>
>>> sender_qobject.connect('clicked(bool)', reciever_qobject.method)<br>
# now reciever_qobject's MetaObject register a new slot signed as 'method(bool)', <br>
# incremental use of the thing (not poluted)<br>
# if the (promoted) slot is connect again with the same signature, it is ignored. <br>
# if a new one signature is used register the new one (eg. 'method()')<br>
# this is valid for the instance.<br>
<br>
- If we want to connect any kind of signal to a function, ordinary
method, or lambda expression, python-qt4 create s a dummy fake QObject
(transparently) that proxies the signal for you:<br>
<br>
>>> sender.connect('clicked()', reciever.method) <br>
>>> sender.connect('clicked()', a_function)<br>
>>> sender.connect('clicked()', lambda: QApplication.quit() )<br>
<br>
# inside python-qt4 (transparent)<br>
class FakeSlot(QObject):<br>
   def __init__(self, destiny):<br>
       self.destiny = destiny   # python callable<br>
   def callback(self, *args, **kw):<br>
       self.destiny(*args, **kw)   # redirect the call<br>
<br>
>>> fakeslot = FakeSlot(my_callable)<br>
>>> sender.connect('clicked(bool)', fakeslot.callback)<br>
<br>
Nice, eh?<br>
<br>
[Eric Jardim]<br>