| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 2 | |
Hi,
[Qt 4.4.0 beta 1]
I am running into a situation that I imagine to be quite common. I am making
an object (ok, a widget) that provides an interfact with some signals and
slots to the outside world (the rest of my program). However, most of the
slots in this interface only need a very simple relaying to another,
embedded objects' slot. I do not want to make these embedded objects public,
in order to create a clean API. The fact that an embedded object handles the
work is an implementation detail, after all.
So, I find myself in a situation where I define and implement slot methods
that do nothing than call a slot on one of the embedded objects. Somehow,
that feels a bit redundant and I figured that it must be possible to do that
in a smarter way. AFAIK, you can not connect a SLOT to another SLOT (but you
can connect a SIGNAL to another SIGNAL). How do other people solve this
situation? Is there some Qt trick where you can use something like a connect
on a slot and be done with it? Or do I need to create some kind of macro to
do it for me?
Currently, I am writing something like this:
class MyClass: public QObject {
Q_OBJECT
public:
MyClass(QObject* parent);
public slots:
void slot1(int);
void slot2(const QString&);
private:
QObject* m_embeddedObject;
QObject* anotherEmbeddedObject;
};
MyClass::slot1(int value) {
m_embeddedObject->slot1(value);
}
MyClass::slot2(const QString& value) {
m_anotherEmbeddedObject->slot2(value);
}
This is annoying work, and clutters up the implementation. I think it would
be extremely usefull if it were possible to just write a header like this:
class MyClass: public QObject {
Q_OBJECT
public:
MyClass(QObject* parent);
public relay_slots:
void slot1(int) m_embeddedObject, SLOT(slot1(int));
void slot2(const QString&) m_anotherEmbeddedObject, SLOT(slot2(const
QString&));
private:
QObject* m_embeddedObject;
QObject* anotherEmbeddedObject;
};
In this scenario, one would not have to further implement slot1 or slot2,
the uic would take care of just creating a relay to the slot for you.
Alternatively, something like this would be cool (and closer to the current
QObject::connect()) as well:
class MyClass: public QObject {
Q_OBJECT
public:
MyClass(QObject* parent);
public relay_slots:
void slot1(int);
void slot2(const QString&);
private:
QObject* m_embeddedObject;
QObject* anotherEmbeddedObject;
};
MyClass::MyClass(QObject* parent):
QObject(parent)
{
connect(SLOT(slot1(int)), m_embeddedObject, SLOT(slot1(int)));
connect(SLOT(slot2(const QString&)) , m_anotherEmbeddedObject,
SLOT(slot2(const QString&)));
}
That is: just use the slots as signals if you declare them as such and make
your connections just like you are used to. I know that I could just use
signals in my class instead of slots (you can connect a signal to a signal,
after all), but that IMHO does not result in a clean API. Having a signal in
the API communicates another message than having a slot in the API. I do not
want others, outside of the class, to connect to the signal/relay_slot
either, so using signals would not really do.
Am I missing something in the Qt API that already makes this possible? What
do other people think about this?
Andreé
--
[ signature omitted ]
On Wednesday 09 April 2008 11:44:53 André Somers wrote:
> AFAIK, you can not connect a SLOT to another SLOT
> (but you can connect a SIGNAL to another SIGNAL).
That's correct.
Signals are implemented by moc itself and they are, by definition, "outgoing".
That's why you can connect a signal to a slot or another signal. Slots,
however, are "incoming". And they are your own code. You can't connect a slot
to another slot, much less to a signal.
Your case, however, isn't of slot-slot connection. It's that you want a
separate class to have the functions that implement the slots. And you want
the user of your own class to be completely unaware of the fact.
The first solution I can think of is: dump moc.
Change the Q_OBJECT in your class to Q_OBJECT_DEFS and implement yourself the
qt_metacall function, as well as the object arrays. A simple way of doing
that is to generate it once with moc, then copy the .moc file's contents to
your .cpp, hand-editing it to do whatever is necessary.
This is, as expected, undocumented. But it's guaranteed to work now and
forever, because we can't change the behaviour of qt_metacall on the many
applications and libraries out there.
> class MyClass: public QObject {
> Q_OBJECT
>
> public:
> MyClass(QObject* parent);
>
> public relay_slots:
> void slot1(int) m_embeddedObject, SLOT(slot1(int));
> void slot2(const QString&) m_anotherEmbeddedObject, SLOT(slot2(const
> QString&));
>
> private:
> QObject* m_embeddedObject;
> QObject* anotherEmbeddedObject;
> };
This code excerpt reminded me of something we use in Qt. And in KDE.
As a Qt developer, I'll tell you: there's no documented way of doing that.
But if I put my KDE hat on, I'll tell you this: Q_PRIVATE_SLOT. It's an
undocumented macro -- meaning it can be removed or changed at any time --
that does exactly what you want. Your class would look like:
class SubObject; class AnotherSubObject;
class MyClass: public QObject {
Q_OBJECT
public:
MyClass(QObject* parent);
private:
Q_PRIVATE_SLOT(m_embeddedObject, void slot1(int))
Q_PRIVATE_SLOT(m_anotherEmbeddedObject, void slot2(const QString&))
SubObject* m_embeddedObject;
AnotherSubObject* anotherEmbeddedObject;
};
Note that the *definitions* of SubObject and AnotherSubObject aren't in the
public .h files. They are just forward-declared. We use that technique all
over the place in Qt for the QFooPrivate classes.
However, those classes have to be visible to moc. Which means, in general, you
will have to add at the bottom of your .cpp file:
#include "myclass.moc"
That macro was designed for private slots. That is, when a class needs to
receive a signal from wherever, but the user of that class isn't supposed to
use that slot. That's why we those slots are also named _q_someName in Qt.
However, any name can be given to your slot and they are just normal slots
from the point of view of QObject::connect().
One more thing: neither qdoc3 nor doxygen will document those. You may want to
trick them with some #ifdef magic.
> MyClass::MyClass(QObject* parent):
> QObject(parent)
> {
> connect(SLOT(slot1(int)), m_embeddedObject, SLOT(slot1(int)));
> connect(SLOT(slot2(const QString&)) , m_anotherEmbeddedObject,
> SLOT(slot2(const QString&)));
> }
This is technically possible to implement, but not desirable. Right now, each
connect() call adds an entry to a list of (sender,signal,receiver,slot)
tuples. [It's more complicated than that, but the analogy holds]
To relay a slot, we'd have to have a separate list of
(receiver,slot,overrider,overridingSlot). But that brings the questions:
1) what happens if you override twice the same slot?
2) should you be allowed to hijack any slot from any Qt class?
This may have some interesting use-cases, but it's not something we'll add
right now.
--
[ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
Hi Thiago,
Thank you very much for your long and insightfull reply.
"Thiago Macieira" <thiago.macieira@xxxxxxxxxxxxx> wrote in message
news:200804091217.22751.thiago.macieira@xxxxxxxxxxxxxxxx
> On Wednesday 09 April 2008 11:44:53 André Somers wrote:
>> AFAIK, you can not connect a SLOT to another SLOT
>> (but you can connect a SIGNAL to another SIGNAL).
>The first solution I can think of is: dump moc.
>
> Change the Q_OBJECT in your class to Q_OBJECT_DEFS and implement yourself
> the
> qt_metacall function, as well as the object arrays. A simple way of doing
> that is to generate it once with moc, then copy the .moc file's contents
> to
> your .cpp, hand-editing it to do whatever is necessary.
Hmm... While this would work and could be workable in specific cases, I
think it sounds like the perfect recipe for a maintance nightmare. What will
happen if I want to change the class, adding a new slot perhaps? Re-run moc
and re-edit the resulting .moc file? Not a nice scenario...
> But if I put my KDE hat on, I'll tell you this: Q_PRIVATE_SLOT. It's an
> undocumented macro -- meaning it can be removed or changed at any time --
> that does exactly what you want. Your class would look like:
> class SubObject; class AnotherSubObject;
> class MyClass: public QObject {
> Q_OBJECT
>
> public:
> MyClass(QObject* parent);
>
> private:
> Q_PRIVATE_SLOT(m_embeddedObject, void slot1(int))
> Q_PRIVATE_SLOT(m_anotherEmbeddedObject, void slot2(const QString&))
>
> SubObject* m_embeddedObject;
> AnotherSubObject* anotherEmbeddedObject;
> };
>
> Note that the *definitions* of SubObject and AnotherSubObject aren't in
> the
> public .h files. They are just forward-declared. We use that technique all
> over the place in Qt for the QFooPrivate classes.
> (...)
> However, any name can be given to your slot and they are just normal slots
> from the point of view of QObject::connect().
This is very interesting indeed. I will look into this. One question: I do
not see how I set the name of the slot in the interface using this scenario.
Can you give me a clue how to do that?
>> MyClass::MyClass(QObject* parent):
>> QObject(parent)
>> {
>> connect(SLOT(slot1(int)), m_embeddedObject, SLOT(slot1(int)));
>> connect(SLOT(slot2(const QString&)) , m_anotherEmbeddedObject,
>> SLOT(slot2(const QString&)));
>> }
>
> This is technically possible to implement, but not desirable.
I think it *would* be desirable, because it would yield by far the most
flexible solution.
> To relay a slot, we'd have to have a separate list of
> (receiver,slot,overrider,overridingSlot). But that brings the questions:
>
> 1) what happens if you override twice the same slot?
> 2) should you be allowed to hijack any slot from any Qt class?
>
> This may have some interesting use-cases, but it's not something we'll add
> right now.
What if you think of it not in terms of overriding, but in terms of piggy
bagging? That is: connecting a slot to a slot would not override the
existing slot, but it would only make sure that the piggy bagged slot would
*also* be executed. That answers your questions:
1) You don't override the slot at all, so there is no problem. Just like you
can connect multiple slots to a signal: they would just *both* be executed.
2) Sure you would! Again: not hijack, but piggy bag.
Of course, piggy bagged slots would only be executed if the slot was called
through a signal, but that is a minor limitation I think. I think it would
make sense if the original slot was guaranteed to be executed first, and
then the piggy bagged slots in arbitrairy order.
For my third example, the code would have to be adjusted like this:
public relay_slots:
void slot1(int) {};
void slot2(const QString&) {};
That is: just declare an empty implementation for the slot, and connect them
later on.
This solution is more flexible than your second solution, because it would
allow for things like connecting multiple times to a single slot. It can
also help to bring some flexibility back to Qt in subclassing that was lost
with the extensive use of private implementations, because this way you
would be able to add some functionality at least to slots, even if you can
not override the original code.
I really think that this would be an awesome future extension of the Qt
signal/slot system. It would make it possible to write more elegant, smaller
and better mainable code, and it could open up some interesting new options
of extending classes functionality without subclassing. It would fit nicely
in the "code less, do more" slogan of Qt :-)
Again: thank you for your insights. I will investigate your suggestions.
André
--
[ signature omitted ]
On Thursday 10 April 2008 10:17:59 André Somers wrote:
> > class SubObject; class AnotherSubObject;
> > class MyClass: public QObject {
> > Q_OBJECT
> >
> > public:
> > MyClass(QObject* parent);
> >
> > private:
> > Q_PRIVATE_SLOT(m_embeddedObject, void slot1(int))
> > Q_PRIVATE_SLOT(m_anotherEmbeddedObject, void slot2(const QString&))
> >
> > SubObject* m_embeddedObject;
> > AnotherSubObject* anotherEmbeddedObject;
> > };
> >
> > Note that the *definitions* of SubObject and AnotherSubObject aren't in
> > the
> > public .h files. They are just forward-declared. We use that technique
> > all over the place in Qt for the QFooPrivate classes.
> > (...)
> > However, any name can be given to your slot and they are just normal
> > slots from the point of view of QObject::connect().
>
> This is very interesting indeed. I will look into this. One question: I do
> not see how I set the name of the slot in the interface using this
> scenario. Can you give me a clue how to do that?
You have to understand what Q_PRIVATE_SLOT is trying to fix. Here's what we
had in Qt3 code (as well as KDE 3 libraries):
class MyDialog: public QDialog
{
Q_OBJECT
[...]
private slots:
void button1Clicked();
void button2Clicked();
void timedout();
};
As you can see, those are normal slots, albeit private. The privateness of
them means you can't call them like normal functions from outside the class
or its friends, but you can still do:
connect(timer, SIGNAL(timeout()), dialog, SLOT(timedout()));
That's probably what that class's constructor does anyways.
During the Qt4 development process, the use of the d pointer (a.k.a. "private
implementation/pimpl" model) was greatly enhanced. We moved almost all of the
private functions and members from the main class (the one you see and use)
to the Private class. [The exceptions are classes meant for really fast
access, like QString]
We wanted to move the private slots too, so the Q_PRIVATE_SLOT macro was
introduced. It expands to nothing in C++, but moc parses it just like the
above code! The only difference is in the qt_metacall function: instead of
calling
slotName(arguments)
it calls:
firstarg->slotName(arguments)
But, like I said, nothing changes in the QObject::connect statement.
Which is why, in Qt 4.2, we renamed all of those private slots to start with
_q_ (underscore, q, underscore).
--
[ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
Thiago Macieira wrote:
> Change the Q_OBJECT in your class to Q_OBJECT_DEFS and implement yourself the
> qt_metacall function, as well as the object arrays. A simple way of doing
> that is to generate it once with moc, then copy the .moc file's contents to
> your .cpp, hand-editing it to do whatever is necessary.
>
> This is, as expected, undocumented. But it's guaranteed to work now and
> forever, because we can't change the behaviour of qt_metacall on the many
> applications and libraries out there.
>
Thank you for this insight - this is exactly the situation I have found
myself in. On the other hand, I found another solution: "reimplement"
connect.
I have a class MainClass (incidentally, it's even not a QObject
itself...) which has as a private member a pointer to a GUI handler
class. This class serves as the top level for all of my GUI dialogs.
(Yes, it's crazy... but necessary due to my unusual threading
environment - this gets me all the GUI code in a single thread.) I
don't want the "outside world" to have any access to the GUI class
directly, so I have functions like this:
*bool* MainClass::*showGui*(*const* *char** guiSlot)
{
*return* myGui->*metaObject*()->*invokeMethod*(myGui, guiSlot, Qt::QueuedConnection);
}
*bool* MainClass::*connectGui*(*char* *const** widgetName, *char* *const** *signal*, QObject *const** receiver, *char* *const** method)
{
*for* (QList<QWidget*>::*const_iterator* curWidget = myGui->widgets.*constBegin*();
curWidget != myGui->widgets.*constEnd*(); ++curWidget)
{
*if* ((*curWidget)->*metaObject*()->*className*() == widgetName)
*return* myGui->*connect*(*curWidget, *signal*, receiver, method, Qt::QueuedConnection);
}
*qWarning*() << *QString*("'%1' not found as GUI class").*arg*(widgetName);
*return* *false*;
}
My MainClass is the base of the application and thus a singleton, and so
has an instance() function. So when someone wants to display a dialog
and get a response back, they call ask the app to connect them to the
appropriate GUI class, and then call the app's showGui method.
--
[ signature omitted ]
I am looking to embed a command-line shell into my Qt 4 app. Does anyone know of a QWidget based command-line shell, or perhaps a shell that can be embedded into a Qwidget? I am looking for a solution for both windows and linux/unix/mac (separate solutions will work if required). A further requirement is that I need to be able to parse/analyze the std-out/std-err output so that I can present the user with options (i.e. visit build errors in a source editor, etc.). Thanks in advance, -jim ------------------------ Jim Boyd SciTools inc. www.scitools.com -- [ signature omitted ]
I have not looked into QScript very much and therefore have not thought about QScript support in the shell. I'll have to look into that. My application has a perl api published for the user to create/run custom scripts in the application. The need for the shell arises to support the customer's ability to run shell commands (include perl scripts) and interact with the output of these commands in the application. We have a simple interface that allows them to run a command, one process at a time, and interact with the results. We plan to have a complete shell for them to work in. We have prototyped a solution using QTextEdit, but thought a third party solution may exist that would provide the functionality we are looking for. -jim -----Original Message----- From: Peter Hackett [mailto:Peter.Hackett@xxxxxxxxxxxx] Sent: Friday, April 11, 2008 10:50 AM To: Jim Boyd Cc: qt-interest@xxxxxxxxxxxxx Subject: Re: QWidget Command-Line shell Are you expecting to integrate this with QScript? I've done this (but for a commercial app.) It not *too* hard but it definitely building from lower level primitives like QTextEdit, etc. My "not thinking about it too hard" notion is that that Trolltech should provide something higher level for this kind of thing. However, it may be difficult to create something compellingly useful that's not difficult to use. Jim Boyd wrote: > I am looking to embed a command-line shell into my Qt 4 app. > > Does anyone know of a QWidget based command-line shell, or perhaps a shell > that can be embedded into a Qwidget? I am looking for a solution for both > windows and linux/unix/mac (separate solutions will work if required). > > A further requirement is that I need to be able to parse/analyze the > std-out/std-err output so that I can present the user with options (i.e. > visit build errors in a source editor, etc.). > > Thanks in advance, > -jim > ------------------------ > Jim Boyd > SciTools inc. > www.scitools.com > > -- > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body. > List archive and information: http://lists.trolltech.com/qt-interest/ > > -- [ signature omitted ]
First you're not missing anything.... you just cant connet slots to slots...
However, as you pointed out, you can connect signals to signals..
What I would do... is have signals on the container class then connect to those signals on the outside world...
Then in your constructor, connect those signals to the inner widgets..
Ie
class MyClass: public QObject {
Q_OBJECT
public:
MyClass(QObject* parent);
Signals:
void sig1(int);
void sig2(const QString&);
private:
QObject* m_embeddedObject;
QObject* anotherEmbeddedObject;
};
MyClass::MyClass(QObject* parent):
QObject(parent)
{
connect(SIGNAL(sig1(int)), m_embeddedObject, SLOT(slot1(int)));
connect(SIGNAL(sig2(const QString&)) , m_anotherEmbeddedObject,
SLOT(slot2(const QString&)));
}
Scott
> -----Original Message-----
> From: André Somers [mailto:andre@xxxxxxxxxxxxxxxx]
> Sent: Wednesday, April 09, 2008 2:45 AM
> To: qt-interest@xxxxxxxxxxxxx
> Subject: Relaying slots
>
> Hi,
>
> [Qt 4.4.0 beta 1]
>
> I am running into a situation that I imagine to be quite common. I am
> making
> an object (ok, a widget) that provides an interfact with some signals
> and
> slots to the outside world (the rest of my program). However, most of
> the
> slots in this interface only need a very simple relaying to another,
> embedded objects' slot. I do not want to make these embedded objects
> public,
> in order to create a clean API. The fact that an embedded object
> handles the
> work is an implementation detail, after all.
>
> So, I find myself in a situation where I define and implement slot
> methods
> that do nothing than call a slot on one of the embedded objects.
> Somehow,
> that feels a bit redundant and I figured that it must be possible to do
> that
> in a smarter way. AFAIK, you can not connect a SLOT to another SLOT
> (but you
> can connect a SIGNAL to another SIGNAL). How do other people solve this
> situation? Is there some Qt trick where you can use something like a
> connect
> on a slot and be done with it? Or do I need to create some kind of
> macro to
> do it for me?
>
> Currently, I am writing something like this:
>
> class MyClass: public QObject {
> Q_OBJECT
>
> public:
> MyClass(QObject* parent);
>
> public slots:
> void slot1(int);
> void slot2(const QString&);
>
> private:
> QObject* m_embeddedObject;
> QObject* anotherEmbeddedObject;
> };
>
> MyClass::slot1(int value) {
> m_embeddedObject->slot1(value);
> }
>
> MyClass::slot2(const QString& value) {
> m_anotherEmbeddedObject->slot2(value);
> }
>
>
> This is annoying work, and clutters up the implementation. I think it
> would
> be extremely usefull if it were possible to just write a header like
> this:
>
>
> class MyClass: public QObject {
> Q_OBJECT
>
> public:
> MyClass(QObject* parent);
>
> public relay_slots:
> void slot1(int) m_embeddedObject, SLOT(slot1(int));
> void slot2(const QString&) m_anotherEmbeddedObject,
> SLOT(slot2(const
> QString&));
>
> private:
> QObject* m_embeddedObject;
> QObject* anotherEmbeddedObject;
> };
>
>
> In this scenario, one would not have to further implement slot1 or
> slot2,
> the uic would take care of just creating a relay to the slot for you.
> Alternatively, something like this would be cool (and closer to the
> current
> QObject::connect()) as well:
>
>
> class MyClass: public QObject {
> Q_OBJECT
>
> public:
> MyClass(QObject* parent);
>
> public relay_slots:
> void slot1(int);
> void slot2(const QString&);
>
> private:
> QObject* m_embeddedObject;
> QObject* anotherEmbeddedObject;
> };
>
> MyClass::MyClass(QObject* parent):
> QObject(parent)
> {
> connect(SLOT(slot1(int)), m_embeddedObject, SLOT(slot1(int)));
> connect(SLOT(slot2(const QString&)) , m_anotherEmbeddedObject,
> SLOT(slot2(const QString&)));
> }
>
>
> That is: just use the slots as signals if you declare them as such and
> make
> your connections just like you are used to. I know that I could just
> use
> signals in my class instead of slots (you can connect a signal to a
> signal,
> after all), but that IMHO does not result in a clean API. Having a
> signal in
> the API communicates another message than having a slot in the API. I
> do not
> want others, outside of the class, to connect to the signal/relay_slot
> either, so using signals would not really do.
>
> Am I missing something in the Qt API that already makes this possible?
> What
> do other people think about this?
>
> Andreé
>
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
--
[ signature omitted ]
Hi, "Scott Aron Bloom" <Scott.Bloom@xxxxxxxxxxxx> wrote in message news:7DB34253D57D2B47AEB656218FE6AAEF082267@xxxxxxxxxxxxxxxxxxxxxxxxx > First you're not missing anything.... you just cant connet slots to > slots... > > However, as you pointed out, you can connect signals to signals.. Thanks, but that was not what I was looking for. I also thought of that solution, but I think it results in a weird interface for the class, and it exposes implementation details of the class. 1) It is not obvious from the semantics that you have to connect your signal to a *signal* in the interface of the class to get something done. A signal is supposed to be outgoing, while a slot is supposed to be incomming. I understand it would technically work, but it would IMHO result in bad API design. 2) It exposes implementation details, because it is obvious that the class is not doing something itself but is using something else to do it. That is an implementation detail that should be hidden, again IMHO. Thanks for your insights though. André -- [ signature omitted ]
While I agree in principle with your concern, I will say, I have seen many classes that do exactly this... Call them private signals and comment that they are inward...
Also, while I have used the private slots, IMO, until trolltech publicly exposes the macro in documentation, it should be avoided....
As said by someone else, there is always a line to walk between clean api and lots of hidden code from the interface :)
One way I have used to avoid the exposure of the innerds... is to have a "connect to" type method...
You send in the connectee class, and it connects to all the inner workings for you...
The private d method that TT uses, is great for an API, but can be VERY problematic if you as a user need to override the functionality... since the flow of the class becomes so internal that not enough of a classes algorithms are exposed to virtual functions...
If it was me... I would have slots in the class that either re-emit a different signal inward, or explicitly call the sub classes methods..
I might even create my own macro since it would be very repetitive code...
Ie
#define RESEND_TO_SUBOBJ_A( FuncNam ) \
Void ClassName::##FuncName() \
{ \
objA->##FuncName(); \
}
Or something like that.. I always wind up googling complex macros like that...
Good luck
Scott
> -----Original Message-----
> From: André Somers [mailto:andre@xxxxxxxxxxxxxxxx]
> Sent: Thursday, April 10, 2008 12:37 AM
> To: qt-interest@xxxxxxxxxxxxx
> Subject: Re: Relaying slots
>
> Hi,
>
> "Scott Aron Bloom" <Scott.Bloom@xxxxxxxxxxxx> wrote in message
> news:7DB34253D57D2B47AEB656218FE6AAEF082267@xxxxxxxxxxxxxxxxxxxxxxxxx
> > First you're not missing anything.... you just cant connet slots to
> > slots...
> >
> > However, as you pointed out, you can connect signals to signals..
> Thanks, but that was not what I was looking for. I also thought of that
> solution, but I think it results in a weird interface for the class,
> and it
> exposes implementation details of the class.
> 1) It is not obvious from the semantics that you have to connect your
> signal
> to a *signal* in the interface of the class to get something done. A
> signal
> is supposed to be outgoing, while a slot is supposed to be incomming. I
> understand it would technically work, but it would IMHO result in bad
> API
> design.
> 2) It exposes implementation details, because it is obvious that the
> class
> is not doing something itself but is using something else to do it.
> That is
> an implementation detail that should be hidden, again IMHO.
>
> Thanks for your insights though.
>
> André
>
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
--
[ signature omitted ]
Am Mittwoch, 9. April 2008 schrieb André Somers: > I am running into a situation that I imagine to be quite common. I am > making an object (ok, a widget) that provides an interfact with some > signals and slots to the outside world (the rest of my program). However, > most of the slots in this interface only need a very simple relaying to > another, embedded objects' slot. I do not want to make these embedded > objects public, in order to create a clean API. The fact that an embedded > object handles the work is an implementation detail, after all. > So, I find myself in a situation where I define and implement slot methods > that do nothing than call a slot on one of the embedded objects. Somehow, > that feels a bit redundant and I figured that it must be possible to do > that in a smarter way. AFAIK, you can not connect a SLOT to another SLOT > (but you can connect a SIGNAL to another SIGNAL). How do other people solve > this situation? Is there some Qt trick where you can use something like a > connect on a slot and be done with it? Or do I need to create some kind of > macro to do it for me? <snip> > Am I missing something in the Qt API that already makes this possible? What > do other people think about this? That is the price you pay for a nice clean api with the "interface"-pattern. You have to implement a lot of stuff. And I concur that it is not clean to implement lots of signals in the external api. You could have the public-header get generated by some python/bash/m4/etc. script, but I don't think that is usable in practice. Could be you get different headers on different systems. Not something you want for a public interface... So you are probably stuck to implementing a lot of slots in your interface-class. Arnold -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.