Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在不从QObject派生的情况下使用信号和插槽?_C++_Qt_Qt Signals_Qobject_Slot - Fatal编程技术网

C++ 如何在不从QObject派生的情况下使用信号和插槽?

C++ 如何在不从QObject派生的情况下使用信号和插槽?,c++,qt,qt-signals,qobject,slot,C++,Qt,Qt Signals,Qobject,Slot,或者以其他方式表述我的问题(尽管它并没有解决我的问题): 我需要类中的信号和插槽功能,但我假设如果没有从QObject class MyClass { signals: importantSignal(); public slots: importantSlot(); }; 问题似乎是我需要从QObject派生来使用信号和插槽。。。但是我需要默认构造函数MyClass。但是由于QObject的以下特性,我无法构造它们: 我试了很多 所以我的课堂应该是这样的: #include &

或者以其他方式表述我的问题(尽管它并没有解决我的问题):

我需要类中的信号和插槽功能,但我假设如果没有从
QObject

class MyClass
{
signals:
   importantSignal();
public slots:
   importantSlot();
};
问题似乎是我需要从
QObject
派生来使用信号和插槽。。。但是我需要默认构造函数
MyClass
。但是由于
QObject
的以下特性,我无法构造它们:

我试了很多

所以我的课堂应该是这样的:

#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
{
Q_对象
公众:
显式MyClass(QObject*parent=0);//由qtcreator为QObject派生类自动生成
MyClass(常数MyClass*其他);
信号:
重要信号();
公众时段:
importantSlot();
};
我需要默认构造函数
MyClass

那么,是否有可能避免出现“'QObject::QObject'无法访问类'QObject'中声明的私有成员”错误

或者,是否有可能在不使用
QObject
的情况下使用信号和插槽

class MyClass
{
signals:
   importantSignal();
public slots:
   importantSlot();
};

我很高兴得到任何建议。

如果您想使用信号/插槽模式实现事件驱动功能,但不想在Qt的范围内工作(即,您想在需要复制构造函数的STL容器等内部使用类),我建议使用


否则,不,如果不从
QObject
派生,您就不可能做您想做的事情,因为该基类是处理Qt运行时信号/插槽功能的。如果不使用
QObject
/
qu对象,您就不能使用Qt的信号/插槽机制


理论上,您可以创建一个虚拟QObject并将其组合到类中。然后,虚拟机将把插槽调用转发给您的类。由于Liz在评论中描述的原因,您可能会遇到生命周期管理问题。

如果您想要一个具有
QObject
功能的可复制对象,您需要成员身份(通过指针)而不是继承

您可以从
QObject
派生类
Handler
,其中
Handler
的slot调用
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);
}
struct NonQObjectHandler{
虚拟~NonQObjectHandler(){}
虚空接收(整数,浮点)=0;
};
类处理程序:公共非QObjectHandler{
结构接收器;
std::唯一的ptr m_接收器;
void receive(int,float);//NonQObjectHandler
公众:
Handler();
Handler(const Handler&);//这才是你真正想要的
};
类处理程序::接收方:公共QObject{
Q_对象
私人:
非QObjectHandler*m_handler;
专用插槽:
void receive(int,float);//调用m_处理程序的receive
公众:
接收器(非QoObjectHandler*);
};
Handler::Handler()
:m_接收器(新接收器(本))
{
}
Handler::Handler(常量Handler&old)
:m_接收器(新接收器(本))
{
//复制任何额外的状态变量,但
//接收器被重新创建。
}
Handler::Receiver::Receiver(非QObjectHandler*h)
:m_处理器(h)
{
连接(foo,信号(bar(int,float)),这个,插槽(receive(int,float)));
}
无效处理程序::接收器::接收(int i,float f)
{
m_handler->receive(i,f);
}

自Qt5以来,您只需连接到任何功能即可

connect(&timer, &QTimer::finished,
        &instanceOfMyClass, &MyClass::fancyMemberFunction);

在Qt5中,使用
QObject::connect
信号
连接到
插槽

/*
   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();
}
/*
QMetaObject::Connection QObject::connect(
常量QObject*发送方,
常量字符*信号,
常量字符*方法,
Qt::ConnectionType类型=Qt::自动连接)常量;
*/
#包括
#包括
#包括
int main(int argc,char*argv[]){
QApplication应用程序(argc、argv);
QLineEdit-lnedit;
//将信号'QLineEdit::textChanged'与插槽'lambda函数连接`

QObject::connect(&lnedit,&QLineEdit::textChanged,[&](){qDebug()mh…很好的建议,但我喜欢使用Qt.to late来使用另一个库。但是thx.so有没有办法避免“'QObject::QObject'无法访问在类'QObject'中声明的私有成员?”-错误?是的……不要做需要复制构造函数或赋值运算符的事情。这基本上意味着,通过指针处理从
QObject
派生的对象通常是一个不错的选择,而不是使用可能需要复制才能移动的实例。这并不是说不能使用实例,而是不能复制它们因此,您也不能将它们粘贴在STL容器中,等等。如果您查看QObject的Qt文档,他们会讨论为什么不应该尝试将QObject用作“值”(无复制构造函数),而是作为唯一的对象-换句话说,总是使用指针引用它们。也许有一种方法可以稍微更改您的设计,以便您可以使用信号/插槽。例如,如果您希望将类的实例存储在容器/列表中,您可以改为存储指针。为什么您需要默认的构造函数ctor?或者,你是如何使用这个类的?我使用这个类作为数据持有者,而不是一个struc…-每个实体作为一个元组。我尝试派生QObject的原因是我想使用信号和插槽来加载webcontent(图片)…我还想将实例存储在自己编写的countainer/cluster中。?我需要获取空实例的默认构造函数。mh…我确切地使用我的类来存储值,例如从web加载的图片。例如,图片绘制在地图上(使用marblewidget)。您可以给出一个示例/片段?您可以使用connect()没有Q_对象。但是如果
MyClass
不是从
QObject
派生的,则无法使用emit而没有Q_对象。否,但是您可以省略接收器(第三个参数),并使用静态函数或std::bind/lambdas将对象和成员函数绑定到可调用对象。