How to use templates with QT signals and slots?
Asked Answered
S

2

15

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?

Sixteenmo answered 15/11, 2014 at 21:6 Comment(3)
What about using a QVariant?Baer
Looks interesting, but have never heard about it before!Sixteenmo
Failing that, what about std::any? I found QVariant very difficult to use.Hebetic
Z
14

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)

Zealot answered 15/11, 2014 at 21:18 Comment(2)
This does not answer the question at all. :(Messroom
@Jean-MichaëlCelerier It is better than answer, because plain answer is "It is impossible" Also OP asked "Is there a workaround? Or can my approach simply improved?" And my answer explain how to achieve something similar to template. chernobyllab.blogspot.com/2015/04/…Zealot
B
2

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.

Barbiturism answered 24/6, 2021 at 15:54 Comment(1)
Actually (tested on Qt 5.12.8, QMake 3.1) you can directly connect the template member function (instantiated) to a signal. Given a class MyClass with template member function template <typename T> print() { qInfo() << typeid( T ).name() << "\n"; } then the following connection is a valid one : connect( myButon, &QPushButton::clicked, this, &MyClass::print<int> ).Crista

© 2022 - 2024 — McMap. All rights reserved.