PDA

View Full Version : Problem with signals and slots



ggdev001
19th February 2013, 13:02
Hi, I am writing a Blackberry app have this problem and would greatly appreciate if someone could help.
The situation is as follows.

I have code:




void MYNetworkClass::requestFinished(QNetworkReply* reply)
{

// Check the network reply for errors
if (reply->error() == QNetworkReply::NoError)
{
// read response
const QByteArray response(reply->readAll());
qDebug() <<"Response: "<< response;

JsonDataAccess jda;
QVariantMap results = jda.loadFromBuffer(response).toMap();

QVariantMap data = results.value("SomeData").toMap();

emit signalSuccess(data); // I reach here ....

// however actually when I click "Step Over" in debug mode, and try to exit the function
// afterwards I get such "error" saying: No source available for "QMetaObject::activate() at 0xb9668da7" - highlighted in red.



}
else
{
qDebug() << "\n Problem with the network";
qDebug() << "\n" << reply->errorString();
}


In MyNetwork class I have also added the signal definition in the header file:




signals:

void signalSuccess(QVariantMap result);

Now, elsewhere when someone calls a method of MyNetworkClass object which invokes requestFinished,

I want to catch the signal that is emitted by the requestFinished - as shown above.




MyNetworkClass *network = new MyNetworkClass();

QMap<QString, QString> params;
params.insert("username", userEmail);

bool res = QObject::connect(network, SIGNAL(signalSuccess(QVariantMap)), this, SLOT(SomeSlotForSignal(QVariantMap)));

Q_ASSERT(res);
Q_UNUSED(res);

network->makePostRequest("Login");

My problem is that the slot SomeSlotForSignal never gets called.. :(( even though the signal is emitted form the requestFinished method and also I have declared SomeSlotForSignal as a slot in the header file ... What can be problem??? Any help??? Thanks.

Added after 18 minutes:

I have solved the problem.

The code I wrote above was contained in some method Say MyMethod of class B.


void ClassB::MyMethod(int param1, int param 2)
{
MyNetworkClass *network = new MyNetworkClass();

QMap<QString, QString> params;
params.insert("username", userEmail);

bool res = QObject::connect(network, SIGNAL(signalSuccess(QVariantMap)), this, SLOT(SomeSlotForSignal(QVariantMap)));

Q_ASSERT(res);
Q_UNUSED(res);

network->makePostRequest("Login");
}
and looked like this:


ClassB *object = new ClassB();
object->MyMethod(param1,param2);

before I was not using pointers and heap allocation, I just had:



ClassB object;
object.MyMethod(param1,param2);

and I think when the requestFinished returned, the above object was already destroyed. ?????
I think/hope so.. Do you think it is correct reasoning???

Santosh Reddy
19th February 2013, 13:03
1. Are there any errors/warning in the Application output?
2. What is MYNetworkClass derived from?
3. Are you having the Q_OBJECT macro in the MYNetworkClass definition


...even though the signal is emitted form the requestFinished method ...
How can you tell the signal is emitted? (I mean when the slot connected is not called)

ggdev001
19th February 2013, 13:06
can you please look at my updated reply??.. Thanks.

ps. I meant that the program was reaching that point in Debug, that is why I said the signal is emitted...

Santosh Reddy
19th February 2013, 13:34
and I think when the requestFinished returned, the above object was already destroyed. ?????
I think/hope so.. Do you think it is correct reasoning???
This will the reason if "network->makePostRequest("Login");" does not emit the signal.

ggdev001
19th February 2013, 13:55
Hi, no the problem was here:


ClassB object;
object.MyMethod(param1,param2);
This way it was not working, because as I said I think the object was destroyed from the stack when
the server returned. Once I changed the above code to:


ClassB *object = new ClassB();
object->MyMethod(param1,param2);

It started to work.


But I have another question now. What are the ways to free the memory I allocated above??
If I call
delete before server returns, I will have same issues as before.
How to avoid this issue? What is the best way to free the memory and where in the code?? Thank you.

Santosh Reddy
19th February 2013, 14:12
One way it to assign a parent (QObject) when you create the object, so that it will deleted when the parent is deleted.
or
you could write a slot for deletion
or
using deleteLater() slot

anda_skoa
19th February 2013, 18:46
using deleteLater() slot

I would go for this one.
Make sure there is a signal emitted for both success and error case and connect them to the object's deleteLater() slot.
Or call deleteLater() in the slots connected to those signal(s).

Cheers,
_