或以其他方式提出我的问题(虽然它没有解决我的问题):'QObject::QObject' cannot access private member declared in class 'QObject'
我的课程中需要SIGNALs和SLOTS功能,但我认为如果不从QObject
派生出来就不可能吗?
class MyClass
{
signals:
importantSignal();
public slots:
importantSlot();
};
问题似乎是我需要从QObject
派生出来使用信号和插槽......但我需要MyClass
的默认构造函数。但由于QObject
的以下特征,我无法构造它们:
No Copy Constructor or Assignment Operator
我尝试了很多......
所以我的上课看起来像那样:
#include <QObject>
class MyClass: public QObject
{
Q_OBJECT
public:
explicit MyClass(QObject *parent = 0); //autogenerated by qtcreator for QObject derived class
MyClass(const MyClass * other);
signals:
importantSignal();
public slots:
importantSlot();
};
我需要MyClass
的默认构造函数。
那么有没有可能避免“'QObject :: QObject'无法访问类'QObject'中声明的私有成员”错误?
或者作为替代方案,是否有可能在没有QObject
的情况下使用信号和插槽?
我很高兴有任何建议。
答案 0 :(得分:11)
如果你想要一个具有QObject
功能的可复制对象,你需要成员资格(通过指针)而不是继承。
您可以从Handler
派生一个类QObject
,其中Handler
的广告位在其父级上调用SomeInterface
个虚拟函数。
struct NonQObjectHandler {
virtual ~ NonQObjectHandler () {}
virtual void receive (int, float) = 0;
};
class Handler : public NonQObjectHandler {
struct Receiver;
std :: unique_ptr <Receiver> m_receiver;
void receive (int, float); // NonQObjectHandler
public:
Handler ();
Handler (const Handler &); // This is what you're really after
};
class Handler :: Receiver : public QObject {
Q_OBJECT
private:
NonQObjectHandler * m_handler;
private slots:
void receive (int, float); // Calls m_handler's receive
public:
Receiver (NonQObjectHandler *);
};
Handler :: Handler ()
: m_receiver (new Receiver (this))
{
}
Handler :: Handler (const Handler & old)
: m_receiver (new Receiver (this))
{
// Copy over any extra state variables also, but
// Receiver is created anew.
}
Handler :: Receiver :: Receiver (NonQObjectHandler * h)
: m_handler (h)
{
connect (foo, SIGNAL (bar (int, float)), this, SLOT (receive (int, float)));
}
void Handler :: Receiver :: receive (int i, float f)
{
m_handler -> receive (i, f);
}
答案 1 :(得分:7)
如果你想使用信号/插槽模式实现事件驱动的功能,但是不想在Qt的范围内工作(即,你想在STL容器内使用你的类,等等,需要复制 - 我建议使用Boost::signal。
否则,不,你不可能在不从QObject
派生的情况下做你想要的事情,因为那个基类是处理Qt运行时信号/插槽功能的。
答案 2 :(得分:2)
如果不使用QObject
/ Q_OBJECT
,则无法使用Qt的信号/插槽机制。
理论上你可以创建一个虚拟QObject并将它组成你的类。然后,假人会将插槽调用转发给您的班级。由于Liz在评论中描述的原因,您可能会遇到终身管理问题。
答案 3 :(得分:2)
从Qt5开始,你可以连接到任何功能
connect(&timer, &QTimer::finished,
&instanceOfMyClass, &MyClass::fancyMemberFunction);
答案 4 :(得分:1)
在Qt5中,您使用QObject::connect
将signal
与slot
联系起来:
/*
QMetaObject::Connection QObject::connect(
const QObject *sender,
const char *signal,
const char *method,
Qt::ConnectionType type = Qt::AutoConnection) const;
*/
#include <QApplication>
#include <QDebug>
#include <QLineEdit>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLineEdit lnedit;
// connect signal `QLineEdit::textChanged` with slot `lambda function`
QObject::connect(&lnedit, &QLineEdit::textChanged, [&](){qDebug()<<lnedit.text()<<endl;});
lnedit.show();
return app.exec();
}
结果: