I STRONGLY NEED to know slot where signal is connected to.
-
I create large application with ability dynamically change connections by user's needs. Some objects (not all) have some signals (not all) which connections must be visible to user in "connections list". User can change connection to another object with appropriate slot. Application watches for ability to connect signal and slot (actually it gives to user only slots which are allowed to be connected to specific signal). When application starts first - all these signals are not connected anywhere. They can be connected by user. And those hand made connections MUST TO BE SAVED to file to be automatically connected in start time.
To implement this all clear and nice I need know - WHERE SOME SIGNAL IS CONNECTED TO. I'm not care about "violating the object-oriented principle of modularity". I STRONGLY NEED THAT. About 70% of application is already implemented. It uses LOTS of Qt features and I cannot turn to other framework. I will not implement another signal-slot subsystem by my own. Existing system works excellent and is completely suitable for me - except one: I DON'T KNOW WHERE SIGNAL IS CONNECTED.
Please help me - give me ability to get information about current signal connection. I need function or method like this:
@QList<const char*> slotsConnected( const char* signal ); // returns pointer to SLOT() like strings or to signature@
and nothing more. I do not accept any other idea, I INSIST on this function.
-
If you wouldn't insist on such a function I would have told you that as far as I know there is no convenient way of accessing such information as connection lists are stored within QObject's private data.
I've seen that people who need such functionality just overload QObject's connect method and keep track of the connections by themselves.
However, you might take a look at the sources of QObject - you'll probably find a more suitable solution for you.
-
I am really sorry, but despite your insistance on how you want this to work, it just doesn't work that way. The way I see it, you have two options:
- Either you keep track of your connections yourself. That's what I do for a similar set of needs, or
- You patch Qt to add the functionality and API you need.
Edit:
I would make a very simple, implicitly or even explicitly shared class that describes a single connection, and actually manages it. That means that if the actual data is destructed, the actual Qt signal/slot connection is also removed. That means that you can easily store such items in a container, and just remove them and be sure that the actual connection they represent is also removed. The containers you store them in can be queried to your hearts content. -
You can insist on this function all you want, but if it's not there, you have no option other than going for a different solution. Obviously QMetaObject keeps a list of connected objects, signals and slots, but I think that this is kept internal on purpose.
Sounds to me like you would have one class managing the connections between objects. That to me would be the place to do the book keeping you are probably going to have to do.
-
If it is kept inside QObject - than this must be told by QObject in next release of Qt. Was ever similar feature officially requested in Qt-interests or else? Are there any other people who would like get this information for next products?
Patching Qt is not a solution because of several reasons.
Overloading can slightly help but this requires inherit QObject to add some data structures and overload connect() and disconnect() methods. This helps in very limited situations - when new class inherits QObject directly.
Closer look to sources to find out solution is not completely bad idea. But it is not good - I think all suitable data structures and methods are private... May be somebody already did this excursus?
-
No, it must not. If you want it badly, you could try to patch Qt to provide this API publicly, and contribute that patch via a merge request on Qt. If you provide good use cases for it, and your API is sane, it may be accepted. Just insisting on it here will not get you the functionality inside Qt.
Like I said: I keep track of connections between components too in one of my applications, and created API to query for such connections (they are also visualized to the user, for instance). However, I simply implemented the bookkeeping for this myself. Really not all that hard, and you end up with API that suits your applications use case directly.
-
Just give me idea - did you inherit QObject, or did you patch it's source code, or made something else?
Why not ask Qt team to just "open the door"? I'm sure lots of people would like have this feature. In other forums I discussed it and many developers told they need same. If we all together will ask for it - probably this finally be solved.
-
Something else: I did (sort of) what I described about an hour ago (under the 'Edit:' note): do my own bookkeeping.
If you "just ask", it may or may be accepted as a task, but if it is, probably a low priority one. Note that Qt managed to have signals and slots be very useful for many, many years without this functionality. I don't think many developers would need it. You could see if there is already a ticket for it in "Jira":http://bugreports.qt.nokia.com, and if there is, vote for it. If it is true that so many developers need this, then it should already been reported, right? However, don't get your hopes up to get this in Qt if you're not willing to contribute the code for it yourself. Open governance works both ways...
-
Note that adding these options to the interface would mean weakening the very thing the whole signal/slot system was designed to more or less enforce. This means that you would have to come up with some very strong use cases indeed, if you want this in the public API.
-
Signal/slot is the basic mechanism of Qt. It appeared in Qt from first time, it works well for years and it doesn't look like a subject to be removed or significantly changed. It can be differently implemented under cover of Qt but I don't see reason why any object itself or why any side object cannot know where signal is connected. At middle 90-s I was registered developer of BeOS. This system had very similar mechanism but OS-wide. And there were no difficulties to know receiver to which sender is connected. (BeOS is dead but because of completely different reason - it was too good for Kingdom Of M$)
Now I see class QObjectPrivate which holds all functionality needed to work with classes and signals in more advanced way. But it is not documented what means it can be changed. All is needed from Nokia - open this class for public, document it and promise not to change without notifications.
And of course needed one method in QObject:
@QObjectPrivate* QObject::getPrivates()
{
return d_ptr;
}@or method returning object of class QObjectConnectionListVector which holds all connection info.
-
Not a chance of that going to happen. That class is private for a reason. Just exposing it like you propose shows me that you have no idea about API design, binary compatibiliy constraints and all that have to do with that. If the functionality to query for connected objects would be added (and that is a very big if), it would take the form of a method on QObject or some other public class. No way QobjectPrivate will become part of the public API.
-
Exactly the content of QObjectConnectionListVector for current QObject is enough for professionals. It could be returned by the one call of new QObject method. Just only one method...
@QObjectConnectionListVector QObject::getConnectionsList()
{
return *d_ptr->ConnectionsList;
}@ -
You can make a merge request in qitorious and add it there.
But whether it goes in, I can't tell you. -
Track it yourself. Write a wrapper of QObject::connect which register the connections somewhere, and after you manage it. something like:
@void register_connect( const QObject * sender, const char * signal,
const QObject * receiver, const char * method,
Qt::ConnectionType type = Qt::AutoConnection )
{
if(QObject::connect(sender, signal, receiver, method, type)){
save_connection(sender, signal, receiver, method, type);
}}
class Connections{
typedef struct{
const QObject * object;
const char * method;
}Endpoint;Endpoint sender; QList<Endpoint> receivers;
};
@
save_connection(..) can use a static structure of objects(beware of race conditions) to record the connection.
And then your function
@
QList<const char*> slotsConnected( const char* signal );
@
which would be more like
@
QList<const char*> slotsConnected( const QObject * sender,const char* signal );
@
can retrieve all connections using this particular structure of Connections objects. -
Well I know this solution. But this does allow register new connections only. This solves problem partially. And exactly this duplicates information already stored inside QObject.
What if registered connection will be disconnected using simple disconnect() function?...
-
[quote author="Gourmand" date="1308159679"]But this does allow register new connections only.
[/quote]
If you have control over your entire library then you can change for your own connections. Describe a bit more the issue,please.[quote author="Gourmand" date="1308159679"]
What if registered connection will be disconnected using simple disconnect() function?...
[/quote]
someObject->disconnect() has a static equivalent, so you'll need to change every occurrence by an equivalence to save_connectionYou may also want to look at :
@void QObject::connectNotify ( const char * signal ) and void QObject::disconnectNotify ( const char * signal )@ -
Exactly registering is not as simple as you think. To make this good working and safe - some complex code required. First, connection deleting can be done by different ways, Second this all must be thread safe. Actually this requires more attention than you show here. But the motto of Qt is "Code less - create more". To code less I need to know where each signal is connected...
-
I think you have been given enough pointers on how you might solve this. It seems to me, you are not willing to take any of them. In the end, you probably will end up having to patch Qt, and either distribute your own, patched version, or argue a convincing case to get your patch merged in Qt proper.
-
I already implemented
@class ConnectorRegister
{
public:
ConnectorRegister();
~ConnectorRegister();bool do_connect( QObject * sender, char * signal, QObject * receiver, char * slot, Qt::ConnectionType type = Qt::AutoConnection ); bool do_disconnect( QObject * sender, char * signal, QObject * receiver, char * slot ); bool are_connected( QObject *sender, char *signal, QObject *receiver, char *slot ); Connection where_connected( QObject* object, char * socket, bool sender ); Qt::ConnectionType get_type( QObject *sender, char *signal, QObject *receiver, char *slot );
private:
QList<Connection> connections;
};@with some extra functionality. For example it stores connections in it's destructor to file and restores them in constructor. And it is thread safe. This class is much better and more powerful than all discussed here. That means - I know what I'm talking about. The BEST solution will be if Qt will have ability get connection info legally from QtCore
-
Taking a different approach to this problem (probably too little, too late), if it is a user action that connects or disconnects the signals and slots, wouldn't it just be simpler to keep track of the connection or disconnection requests that the user has made, rather than rely on introspection of the connections themselves? Saving the requests would be trivial, and then to reconnect them later on, you just read in the requests and make them in the order they were saved.