PDA

View Full Version : Confusing Signal/Slot behaviour, more than one slot firing, why?



hybrid_snyper
6th November 2012, 14:06
Hi, I was wondering if someone could clear something up for me here. I have a User class that holds basic info like name etc that I want to load per user, it another function I have linked up some the signals emitted from the class to the slots in the constrctor. It looks something like this.




connect(userA, SIGNAL(isLoaded()), this, SLOT(onALoaded()));
connect(userB, SIGNAL(isLoaded()), this, SLOT(onBLoaded()));
}

UserData* userA;
UserData* userB

private slots:
void onALoaded()
{
//some A stuff
}

void onBLoaded()
{
//some B stuff
}


What I am finding is that both slots are firing even though the signal originates from two different objects. This obviously cannot be correct, this would mean every push button defined would fire every slot a push button is connected too, so what could have gone wrong in my case?

Thanks

Santosh Reddy
6th November 2012, 15:26
What I am finding is that both slots are firing even though the signal originates from two different objects.
Can you reword this (it looks contradicting statement to me)

If both the object emit signal, both slots will be called.

hybrid_snyper
6th November 2012, 15:29
Can you reword this (it looks contradicting statement to me)

If both the object emit signal, both slots will be called.

Sorry, if isLoaded() fires from userA then both methods, onALoaded() and onBLoaded() run. I would expect onALoaded() to be the only slot that is ran.

ToddAtWSU
6th November 2012, 15:41
It looks like you declare userA and userB after making the connect statements. Is that causing some of your issues? I think we need to see more code to know what exactly is going on.

hybrid_snyper
6th November 2012, 16:16
Ok, below is the class simplified with the content and structure that is relevant to my issue. All compiles fine and runs only problem I am having is the Signal/Slot issue.



class myWidget::myWidgetPrivate : public QObject
{
Q_OBJECT

public:
myWidgetPrivate(myWidget* p)
: parent(p)
{
userA = new UserData;
connect(userA, SIGNAL(isLoaded()), this, SLOT(onALoaded()));

userB = new UserData;
connect(userB, SIGNAL(isLoaded()), this, SLOT(onBLoaded()));
}

UserData* userA;
UserData* userB;

private slots:

void onALoaded()
{
//Do some stuff with A
}

void onBLoaded()
{
//Do some stuff with B
}
};

#include "myWidget.moc"

myWidget::myWidget(QWidget *parent)
: QWidget( parent ),
d( new myWidgetPrivate(this) )
{}

ToddAtWSU
6th November 2012, 17:38
Are you manually emitting isLoaded() signal? If so, where are you emitting this signal from and if not, what class is UserData based off? The code above looks fine, but we are not seeing when/how the signals are being emitted. Can we see where you are emitting the signals to ensure you are not accidentally emitting them for both objects?

Santosh Reddy
6th November 2012, 17:42
Do find any warnings in Application output area?

hybrid_snyper
7th November 2012, 10:04
Are you manually emitting isLoaded() signal? If so, where are you emitting this signal from and if not, what class is UserData based off? The code above looks fine, but we are not seeing when/how the signals are being emitted. Can we see where you are emitting the signals to ensure you are not accidentally emitting them for both objects?

I think I have figured it out, I have another class that is emitting a signal that the UserData class is waiting for. This means that each instance of UserData is firing slots due to a signal from another class. The crude diagram below should highlight what I mean.

Controller -------- signal--------|- UserData A ---signal-- myWidget::onA




|- UserData B ---signal-- myWidget::onB


Sorry for wasting your time, but you have helped me to work the problem.

Thanks.

ToddAtWSU
7th November 2012, 14:10
Not a problem. I solve most of my problems by trying to walk someone else through it and before I finish explaining it, I solve it. So I am glad you figured it out!