PDA

View Full Version : Unbelievable error!



Caius Aérobus
29th November 2007, 22:34
I have 2 differents functions/slots (in the same class) in which I emit the same signal and...one of them works, that is the slot associated to this signal is executed, and the second one does not! I have made a copy-paste of the slot code so as to be sure that it was exactly the same and still this inbelievable error! To sum up my code:


class A
{
public slots:
void sl(<some data type>);
};
class B
{
signals:
void si(<some data type>);
public slots:
void sl1() {emit si(<some data type>);};
void sl2() {emit si(<some data type>);};
};
main()
{
A a;
B b;
QObject::connect(B, SIGNAL(si(<some data type>)), A, SLOT(sl(<some data type>)));
...
}

Of course <some data type> is identical everywhere.
Did anybody face a so strange story?

wysota
29th November 2007, 22:39
No. But if you show us the actual code, maybe we can see the problem. Also look at the terminal while running your application if Qt spits out some warning messages about invalid connections.

Caius Aérobus
29th November 2007, 23:21
No. But if you show us the actual code, maybe we can see the problem. Also look at the terminal while running your application if Qt spits out some warning messages about invalid connections.

Not that easy because my code is huge! But I tried to extract the relevant lines:


class Simulator : public QObject
{
Q_OBJECT

public slots:
void SetPositions(std::vector<std::vector<std::vector<double> > > positions);
}

void
Simulator::SetPositions(std::vector<std::vector<std::vector<double> > > positions)
{
this->Print("%d %d %d (%lf,%lf)", positions.size(), positions[0].size(), positions[0][0].size(), positions[0][0][0], positions[0][0][1]);
}

class Display : public QLabel
{
Q_OBJECT

signals:
void PositionsHaveChanged(std::vector<std::vector<std::vector<double> > > positions);

public slots:
void Clear2();
void mousePressEvent(QMouseEvent *);
}

void
Display::Clear2()
{
this->Print("-> Clear2()");
std::vector<std::vector<std::vector<double> > > pos;
std::vector<double> v(2);
v[0] = v[1] = 1.0;
std::vector<std::vector<double> > p;
p.push_back(v);
pos.push_back(p);
this->Print("%d %d %d (%lf,%lf)", pos.size(), pos[0].size(), pos[0][0].size(), pos[0][0][0], pos[0][0][1]);
emit PositionsHaveChanged(pos);
this->Print("<- Clear2()");
}

void
Display::mousePressEvent(QMouseEvent *e)
{
this->Print("-> mousePressEvent()");
std::vector<std::vector<std::vector<double> > > pos;
std::vector<double> v(2);
v[0] = v[1] = 1.0;
std::vector<std::vector<double> > p;
p.push_back(v);
pos.push_back(p);
this->Print("%d %d %d (%lf,%lf)", pos.size(), pos[0].size(), pos[0][0].size(), pos[0][0][0], pos[0][0][1]);
emit PositionsHaveChanged(pos);
this->Print("<- mousePressEvent()");
}


Display *display = new Display();
Simulator *sim = new Simulator();
QObject::connect(display, SIGNAL(PositionsHaveChanged(std::vector<std::vector<std::vector<double> > >)),
sim, SLOT(SetPositions(std::vector<std::vector<std::vector<double> > >)));


QPushButton *b;
b = new QPushButton(QString::fromLocal8Bit("Clear"));
QObject::connect(b, SIGNAL(clicked()), display, SLOT(Clear2()));


If I clic in the image (the label contains a pixmap) it works but if I clic on the button it does not:



Display: -> mousePressEvent()
Display: 1 1 2 (1.000000,1.000000)
Simulator: 1 1 2 (1.000000,1.000000)
Display: <- mousePressEvent()

Display: -> Clear2()
Display: 1 1 2 (1.000000,1.000000)
Display: <- Clear2()


No error message from Qt.

wysota
29th November 2007, 23:33
Hmm.. the output you pasted seems to indicate that Clear2() is called. What is the output you'd expect?

jacek
29th November 2007, 23:34
When does Simulator print its line?

Caius Aérobus
30th November 2007, 11:19
Hmm.. the output you pasted seems to indicate that Clear2() is called. What is the output you'd expect?

I would expect to obtain exactly the same output since both slots (mousePressEvent and Clear2) have the same code! But obviously Simulator::SetPositions() is called when (mousePressEvent emits the PositionsHaveChanged signal and not called when the signal is emitted by Clear2. This is my problem.

Caius Aérobus
30th November 2007, 11:22
When does Simulator print its line?

in slot SetPositions(), Print() method is basically a printf that adds the name of the class on the left.

wysota
30th November 2007, 12:19
So which slot is not called? SetPositions? Did you remember to register a meta-type for your custom argument types?

jacek
30th November 2007, 12:35
in slot SetPositions(), Print() method is basically a printf that adds the name of the class on the left.
What happens if you place it in the first line of that slot?

Caius Aérobus
30th November 2007, 13:10
What happens if you place it in the first line of that slot?

but that slot has a single line:



void
Simulator::SetPositions(std::vector<std::vector<std::vector<double> > > positions)
{
this->Print("%d %d %d (%lf,%lf)", positions.size(), positions[0].size(), positions[0][0].size(), positions[0][0][0], positions[0][0][1]);
}

Caius Aérobus
30th November 2007, 13:19
So which slot is not called? SetPositions? Did you remember to register a meta-type for your custom argument types?


yes SetPositions(), which receives the emit PositionsHaveChanged() signal when it is emitted by mousePressEvent() but does not receive it when emitted by Clear2().

meta-type? euhhhh actually no but:
- I had in mind that this was related to QVariant class in order to make unions of a limited list of types...
- anyway it does not explain why it works for mousePressEvent() and not for Clear2() (it should either work or not work for both, shouldn't it?)

high_flyer
30th November 2007, 13:44
I can't see in your code a connect statement that connects to the mousePressEvent() slot.
Never mind I see now what you meant.

Caius Aérobus
30th November 2007, 14:07
I can't see in your code a connect statement that connects to the mousePressEvent() slot.
Never mind I see now what you meant.

The mousePressEvent() is "natively" connected to the mouse :-) through the QLabel class, so no need to connect it anymore.

high_flyer
30th November 2007, 14:22
I am not sure what do you mean... after all.
I think you might (if I am getting right what I see in your code and what you say) be confusing the mousePressEvent() *event handler* and the mousePressEvent() slot you have overridden in your QLabel subclass!

wysota
30th November 2007, 14:29
yes SetPositions(), which receives the emit PositionsHaveChanged() signal when it is emitted by mousePressEvent() but does not receive it when emitted by Clear2().

Are you sure the signal indeed gets emited? And don't ask me why shouldn't it be emitted. Just connect some other slot to it and find out.