там 90% макросов нет. и например они сами его юзают в креаторе
На самом деле код QtCreator'a оставил удручающее впечатление. Тролли вовсю используют приватные/недокументированные вещи из исходников Qt вместо того, чтобы исправить саму библиотеку и документацию сделав их публичными. Это лишь говорит о том, что сами тролли при создании QtCreator'a столкнулись с задачами, которые либо сложно либо невозможно решить публичным API Qt. Кстати запросто можно испустить сигнал любого объекта как буд-то он сам его сгенерил:
C++ (Qt)
#include <QtCore/QtGlobal>
#include <QtCore/QtDebug>
#include <QtCore/QCoreApplication>
#include <QtCore/QTimer>
#include <QtCore/QMetaMethod>
class Object : public QObject
{
Q_OBJECT;
public:
Object (QObject* parent = 0) : QObject(parent) {}
virtual ~Object() {}
public slots:
void onTimeout()
{
qDebug() << "Time is out. Sender: " << sender();
qApp->quit();
}
};
/* Another, more complex method
void emitSignal(QObject* obj, const char* name)
{
QMetaObject const* mo = obj->metaObject();
int ind = mo->indexOfMethod(QMetaObject::normalizedSignature(name));
QMetaObject::activate(obj, ind, 0);
}
*/
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
Object object;
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), &object, SLOT(onTimeout()), Qt::QueuedConnection);
QMetaObject::invokeMethod(&timer, "timeout");
//emitSignal(&timer, "timeout()"); // more complex method, doesn't support arguments for now
return a.exec();
}
#include "main.moc"
Обратите внимание, я нигде не запускаю таймер, а он приходит как QTimer::singleShot(0, &object, SLOT(timeout()), так как был искусственно сгенерирован. На деле, если попытаться написать такое:
C++ (Qt)
emit timer.timeout();
То Qt выдаст в консоль ошибку о том, что сигнал является protected. Но конструкция на самом деле рабочая. Задача усложняется лишь тем, что макрос "slots" помещает сигналы всегда в protected секцию и единственный способ сделать сигнал публичным это использовать Q_SIGNAL:
public:
Q_SIGNAL void test();
Но тут может быть проблема, если в приложении используется boost или другая библиотека, которая реализует собственную систему сигналов и слотов. Если так уже нужно чтобы объект генерил сигнал, но по запросу извне, то в случае с собственным классом лучше использовать публичный метод обертку, а в случае с чужими объектами решение я привел выше.