View Full Version : Templates and signals
Ubii
5th December 2010, 01:01
Hi!
Code:
Header
template <class D>
class Signal
: public QObject
{
public:
void signal(D);
signals:
void send(D);
};
cpp
template <class D> void Signal<D>::signal(D data)
{
emit send(data);
}
namespace plot{
Signal* xSignal;
}
//------------------------
plot::xSignal = new Signal();
QObject::connect(plot::xSignal, SIGNAL(send(double)), this, SLOT(notImportant(double)));
Everything still works to compile here but in next step something happend
double data = 0;
plot::xSignal->signal(data);
This code should send a signal to notImportant() like this:
First to "Signal::signal(double)" which send signal to "Signal::send(double)" which is connected to "notImportant(double)".
But I can't compile when I add the last line I got an error message.
Line:
plot::xSignal->signal(data);
Error message is:
error: undefined reference to `Signal<double>::signal(double)''
I am new to templates so it is propably someting wrong there.
Does any of you know whats wrong? :)
Thanks
Ubi
Sorry for my english, I am from Sweden :)
Timoteo
5th December 2010, 03:12
Did you not mean
plot::xSignal = new Signal<double>();
instead of
plot::xSignal = new Signal();
Also where is your constructor for Signal?
wysota
5th December 2010, 10:55
Just to warn you - Qt signals/slots mechanism is unable to cooperate with template classes.
Ubii
5th December 2010, 11:31
Did you not mean
plot::xSignal = new Signal<double>();
instead of
plot::xSignal = new Signal();
Also where is your constructor for Signal?
Yes, somehow chrome removed <double> so I used firefox instead and forgot to add it again.
Just to warn you - Qt signals/slots mechanism is unable to cooperate with template classes.
Thanks for the warning.
Then I do it in some other way :)
Timoteo
6th December 2010, 04:59
As an example of something you could do, I threw together some code real quick. This uses libsigc++.
template<typename rt, typename T> class EmittingObject
{
std::tr1::shared_ptr<T> t;
sigc::signal<rt> m_signal;
public:
EmittingObject()
{
t = std::tr1::shared_ptr<T>(new T);
}
sigc::signal<rt>& getSignal() { return m_signal; }
std::tr1::shared_ptr<T> object() { return t;}
};
/*class demonstrating a trivial connection*/
class XWidget : public EmittingObject<void, QWidget>, public sigc::trackable
{
void handle_signal()
{
this->object()->close();
}
public:
XWidget()
{
getSignal().connect(sigc::mem_fun(this, &XWidget::handle_signal));
}
void doSomethingToCauseAnEmit()
{
if(QMessageBox::question(object().get(), "Hello!", "Keep the widget open?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
getSignal().emit();
}
};
/*quick test piece*/
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
XWidget widget;
widget.object()->show();
while(widget.object()->isVisible())
{
widget.doSomethingToCauseAnEmit();
}
app.exit(0);
}
Sorry for the poor formatting, but that is Visual Assist's fault.
This is a silly example, I know. The basic concept is to sidestep Qt's signal/slot mechanism and employ another (if you truly need this type of thing, you may not!).
Ubii
6th December 2010, 16:27
As an example of something you could do, I threw together some code real quick. This uses libsigc++.
template<typename rt, typename T> class EmittingObject
{
std::tr1::shared_ptr<T> t;
sigc::signal<rt> m_signal;
public:
EmittingObject()
{
t = std::tr1::shared_ptr<T>(new T);
}
sigc::signal<rt>& getSignal() { return m_signal; }
std::tr1::shared_ptr<T> object() { return t;}
};
/*class demonstrating a trivial connection*/
class XWidget : public EmittingObject<void, QWidget>, public sigc::trackable
{
void handle_signal()
{
this->object()->close();
}
public:
XWidget()
{
getSignal().connect(sigc::mem_fun(this, &XWidget::handle_signal));
}
void doSomethingToCauseAnEmit()
{
if(QMessageBox::question(object().get(), "Hello!", "Keep the widget open?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
getSignal().emit();
}
};
/*quick test piece*/
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
XWidget widget;
widget.object()->show();
while(widget.object()->isVisible())
{
widget.doSomethingToCauseAnEmit();
}
app.exit(0);
}
Sorry for the poor formatting, but that is Visual Assist's fault.
This is a silly example, I know. The basic concept is to sidestep Qt's signal/slot mechanism and employ another (if you truly need this type of thing, you may not!).
Thanks for the example! Taught me a lot!
I'm not sure I will use it in this project though, because I don't really need it.
But I am sure it will be usefull in my other projects! :)
Timoteo
6th December 2010, 16:37
Glad you liked it, but like I said it is not meant to be a great example - just something to show what could be a great alternative if enough time is put into it (and a better design - composition would have been more appropriate than inheritance for example).
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.