子类化模板类并连接到信号

Subclassing template class and connect to signal

本文关键字:连接 信号 子类      更新时间:2023-10-16

我正在尝试QQueue子类以添加一些功能。 实际上,我无法子类化,但由于代码很短,我重写了自己的实现:

#ifndef MYQUEUE_H
#define MYQUEUE_H
#include <QObject>
#include <QtCore/qlist.h>
QT_BEGIN_NAMESPACE
template <class T>
class MyQueue : public QList<T>
{
Q_OBJECT
public:
// compiler-generated special member functions are fine!
inline void swap(MyQueue<T> &other) Q_DECL_NOTHROW { QList<T>::swap(other); } // prevent QList<->QQueue swaps
#ifndef Q_QDOC
// bring in QList::swap(int, int). We cannot say using QList<T>::swap,
// because we don't want to make swap(QList&) available.
inline void swap(int i, int j) { QList<T>::swap(i, j); }
#endif
inline void enqueue(const T &t) { QList<T>::append(t); emit enqueued(); }
inline T dequeue() { return QList<T>::takeFirst(); }
inline T &head() { return QList<T>::first(); }
inline const T &head() const { return QList<T>::first(); }
signals:
void enqueued();
};
QT_END_NAMESPACE
#endif // MYQUEUE_H

基本上,每当有东西排队时,它都会发出信号。 我不知道将该信号绑定到插槽的正确语法:

MyQueue<QString> queue;
connect(&queue, &MyQueue::enqueued, this, &MainWindow::process_queue);

错误:在没有模板参数的情况下使用"模板类 MyQueue" connect(&queue, &MyQueue::enqueued, this, &MainWindow::p rocess_queue(; ^

它说我正在使用MyQueue(即模板类(而没有指定模板参数(QString(。

我试图添加它,但我以错误的方式做了:

connect(&queue, &MyQueue<QString>::enqueued, this, &MainWindow::process_queue);
error: 没有匹配函数调用 'MainWindow::connect(MyQueue, void (MyQueue::(((, MainWindow

*, void (MainWindow::*((((('

连接此类信号的正确语法是什么?

Qt使用MOC作为他们的信号和插槽连接;不支持模板。如果您对基本原理感兴趣,可以在此处阅读有关此决定的更多信息:http://doc.qt.io/qt-5/why-moc.html

也就是说,您在示例中展示的所有功能都可以在QStringList中使用,因此在这种情况下,您可以将其视为一个选项。

根据我的评论...您可能MyQueue从具有所需信号的合适基类继承。

class MyQueueBase: public QObject {
Q_OBJECT;
public:
virtual ~MyQueueBase ()
{}
signals:
void enqueued();
};

然后MyQueue变成...

template<class T>
class MyQueue: public MyQueueBase,
public QList<T>
{
public:
/*
* All as before but without the signal declaration.
*/
};

使用上述代码可以连接到基类或派生类...

connect(&queue, &MyQueueBase::enqueued, this, &MainWindow::process_queue);
connect(&queue, &MyQueue<QString>::enqueued, this, &MainWindow::process_queue);