Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use templates with QT signals and slots?

I want to use signals and slots in my program, but unfortunately they should be used for transmitting several different data types (e.g. QString, double, etc.) and I don't want to write twenty different slots just because I need one for each data type. But when I want to declare a slot like

template <typename t>
void Slot1(t data);

QT tells me that it is not possible to use templates in signals and slots. Is there a workaround? Or can my approach simply improved?

like image 625
arc_lupus Avatar asked Nov 15 '14 21:11

arc_lupus


People also ask

How signal and slot works in Qt?

In Qt, we have an alternative to the callback technique: We use signals and slots. A signal is emitted when a particular event occurs. Qt's widgets have many predefined signals, but we can always subclass widgets to add our own signals to them. A slot is a function that is called in response to a particular signal.

Can we connect signal to signal in Qt?

This ensures that truly independent components can be created with Qt. You can connect as many signals as you want to a single slot, and a signal can be connected to as many slots as you need. It is even possible to connect a signal directly to another signal.


2 Answers

Accurate answer: It is impossible

Workaround: You can do something like this with new signals and slots syntax:

QSlider *slid = new QSlider;
QLineEdit *lne = new QLineEdit;

connect(slid,&QSlider::valueChanged,this,&MainWindow::random);
connect(lne,&QLineEdit::textChanged,this,&MainWindow::random);
lne->show();
slid->show();

Slot:

void MainWindow::random(QVariant var)
{
    qDebug() << var;
}

Output:

QVariant(int, 11) 
QVariant(int, 12) 
QVariant(int, 13) 
QVariant(int, 14) 
QVariant(int, 16) 
QVariant(QString, "c") 
QVariant(QString, "cv") 
QVariant(QString, "cvb") 
QVariant(QString, "cvbc") 
QVariant(QString, "cvbcv")

Why? http://qt-project.org/wiki/New_Signal_Slot_Syntax

Possibility to automatically cast the types if there is implicit conversion (e.g. from QString to QVariant)

like image 187
Kosovan Avatar answered Sep 30 '22 21:09

Kosovan


Lambda function could do the trick. For example in your case:

class A : public QObject
{
    Q_OBJECT
signals:
    void signal1();
}

class B : public QObject
{
    Q_OBJECT

    template <typename t>
    void Slot1(t data);
}

A* ptra = new A();
B* ptrb = new B();
connect(ptra, &A::signal1, this, [=](){ptrb->Slot1(666);});

It basically creates a no-name slot in the class that calls the connect function and use this slot to call the template function. In this case, the template function does not have to be a slot.

like image 36
user16308363 Avatar answered Sep 30 '22 21:09

user16308363