标签: qobject

QObject在删除时是否区分堆栈和堆分配的子项?

根据Qt文档:

QObjects在对象树中组织自己.当您使用另一个对象作为父对象创建QObject时,该对象将自动将其自身添加到父对象的children()列表中.父母取得对象的所有权; 即,它将自动删除其析构函数中的子项.

对于我来说,这意味着当一个QObject被删除时,它会通过并在它存储在子列表中的所有指针上调用delete.

但是,没有必要动态分配子项,并且使用堆栈分配的对象构建QObject树是完全合法的.

根据标准规范,对未指向动态分配对象的指针调用delete是未定义的行为,这可能导致从"无"到程序崩溃的任何内容.

IMO不太可能是QObject,它几乎是几乎整个Qt类集合的主干,依赖于可能产生未定义行为的东西.

那么,QObject在删除时是否区分堆栈和堆分配子项?如果是这样,究竟是怎么回事?

c++ qt memory-management undefined-behavior qobject

8
推荐指数
1
解决办法
1873
查看次数

完成()连接到QObject的deletelater的QThread

在这里提出这个问题之前,我已经想了很多并阅读了很多文章.这些文章都没有给我一个正确的答案.

http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

 QThread* thread = new QThread;
 Worker* worker = new Worker();
 worker->moveToThread(thread);
 connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
 connect(thread, SIGNAL(started()), worker, SLOT(process()));
 connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
 connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
 connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
 thread->start();
Run Code Online (Sandbox Code Playgroud)

Worker对象具有新线程的亲和力.

1> Worker完成信号将调用线程上的quit().这将结束线程的事件循环并启动线程完成信号.

2> Worker完成信号连接到worker deleteLater().根据deleteLater()文档

**安排此对象删除.当控制返回到事件循环时,将删除该对象.如果事件循环>未运行

当调用此函数时(例如,在QCoreApplication :: exec()之前在对象上调用deleteLater()),一旦启动事件循环,该对象将被删除.

注意,进入和离开新的事件循环(例如,通过打开模态对话框)将不执行延迟删除; 对于要删除的对象,控件必须返回到调用deleteLater()的事件循环.

注意:不止一次调用此函数是安全的; 在传递第一个延迟删除事件时,将从事件队列中删除该对象的任何挂起事件.**

因此,当没有eventloop时,由于线程已经退出并且它已经提升了完成的信号,我们将不再再次启动相同的线程.在这种情况下,将永远不会处理deleteLater(),因为事件循环不存在,并且根本不会删除worker对象.这不会造成内存泄漏吗?

 connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
 connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
Run Code Online (Sandbox Code Playgroud)

如果我们认为交换这两行将解决问题,那么我还有另外一个问题.QT明确指出,在发出信号时调用插槽的顺序是不确定的

上面提到的文章链接中有很多评论.即便是作者也无法完全回答这个问题

signals quit qthread qobject

7
推荐指数
1
解决办法
9082
查看次数

在Qt中,如何使用Q_OBJECT插槽和具有多重继承的信号?

我查看了相关的问题,找不到任何能解决我所说的内容的内容,所以让我来描述一下.

我有一个类,让我们说foo需要有自己的插槽和信号,但也需要从QXmlDefaultHandler继承(听起来很奇怪,但我在尝试使用QHttp将网站直接读入QBuffer时遇到了这种情况).

class foo: public QXmlDefaultHandler, public QObject
{
    public:
        foo();
        ~foo();

       Q_OBJECT
   public slots:
       void bar();
}
Run Code Online (Sandbox Code Playgroud)

这个代码,如果附带一个cpp连接条到其他地方的信号,将无法编译.您将获得有关QObject的某些成员不是QXmlDefaultHandler成员的错误.另外,你不能移动Q_OBJECT,否则你会因为没有实现某些东西而得到vtable错误(继续!试试吧!).

请看(非常简单)修复我的答案.如果我认为你比我更好地解释它,我会接受投票给你作为公认的答案.

编辑:对于你c ++和Qt兽医,如果你能更好地解释它,请发一个答案.我花了很多时间查看这些信息,所以如果你能做得比我好,请帮助别人.

qt qobject

6
推荐指数
1
解决办法
5660
查看次数

QObject儿童的顺序(战略问题)

对于我的一个项目,我有一个QObject派生对象树,它利用QObject的父/子功能来构建树.

这非常有用,因为我使用了信号和插槽,使用Qt的保护指针并期望父对象在删除时删除子对象.

到现在为止还挺好.不幸的是,现在我的项目要求我管理/改变孩子的顺序.QObject没有提供任何改变其子节点顺序的方法(例外:QWidget的raise()函数 - 但在这种情况下这没用).所以现在我正在寻找一种控制孩子秩序的策略.我有一些想法,但我不确定他们的利弊:



选项A:自定义排序索引成员变量

使用int m_orderIndex成员变量作为排序键,并提供一个sortedChildren()方法,该方法返回按此键排序的QObject列表.

  • 易于实现到现有的对象结构中.
  • QObject::children()方法被覆盖时会出现问题 - 当项目的顺序发生变化时,在循环期间会导致问题,也比默认实现更昂贵.
  • 如果所有排序键相等或0 /默认,则应回退到QObject对象顺序.

选项B:儿童冗余清单

在a中维护一个冗余的子项列表QList,并在创建和销毁子项时添加子项.

  • 需要昂贵的跟踪添加/删除的对象.这基本上导致第二个子/父跟踪和许多信号/时隙.QObject已在内部完成所有这些工作,因此再次执行它可能不是一个好主意.也感觉像为改变孩子的顺序这样的简单事情添加了很多臃肿.
  • 良好的灵活性,因为可以根据需要修改儿童的QList.
  • 允许子进程多次进入QList,或者根本不进入QList(即使它可能仍然是QObject的子进程)

选项C:...?

任何想法或反馈,特别是那些已经在自己的项目中解决过这个问题的人,都会受到高度赞赏.新年快乐!

qt children qt4 qobject

6
推荐指数
1
解决办法
1859
查看次数

QObject有多大?

我很好奇QObject究竟有多大,包括每个实例动态创建的典型私有数据.sizeof由于它们的实施方式,我无法得到那些.

编辑:请注意,我的QObject的典型使用场景的大小,我不是问"如何获得大小"这是其他问题的关键,我问的是谁知道大概的大小,因为很明显,语言本身并没有提供报告的方法.

c++ size qt qobject

6
推荐指数
0
解决办法
192
查看次数

如何在qt connect中将qobject作为参数从信号传递到插槽

我的原始代码将QStringList从信号传递到插槽,然后返回一个QList.一切正常但我需要将QStringList和QList更改为2个不同的子类QObject.从那时起,我一直收到像"首先需要的合成方法"这样的错误,或者只是崩溃而没有任何错误信息.

我知道qt复制了排队连接中传递的所有参数,并且无法复制qobject.所以我没有返回一个qobject,而是认为我会在发出信号之前创建两个qobjects.然后我将传递对每个对象的引用,在slot函数中修改其中一个并使返回值无效.不幸的是,无论我如何编码信号和插槽功能,应用程序仍会崩溃.如何编码信号/插槽函数并将它们连接到两个qobjects作为参数或返回一个qobject?

MyQObject1 obj1("a","b","c");
MyQObject2 obj2();
emit sendSignal(&obj1, &obj2);
// or
MyQObject2 obj2 = emit sendSignal(&obj1);

connect(someObj, SIGNAL(sendSignal(const QObject&)), this, SLOT(receiveSignal(const QObject&)));
Run Code Online (Sandbox Code Playgroud)

receiveSignal()函数不直接创建或修改任何qobject.它必须首先将qobjects传递给另一个函数,然后修改obj2或创建并返回它.任何代码示例将不胜感激.

qt signals connect qobject slot

6
推荐指数
1
解决办法
2万
查看次数

有机会使用QML的非QObject类

至于将C++类型的属性暴露给与QML一起使用的QML类必须是QObjects.我有可能使用非QObjectss(又名POCO,不是从QObjectQt元系统中派生出来的,而是注册的)

如果没有,是否有一个简单的通用包装系统,使我的对象符合QML.我能想到的是将动态属性添加到简单的属性中QObject.

或者有没有办法隐式转换为QML兼容类型,所以我根本不需要包装?

c++ qobject qml

6
推荐指数
1
解决办法
965
查看次数

QML:获取 QObject 父级

QObjectQML 引入了与可视化树(QtQuick 场景图)分离的所有权 ( ) 树。

  • parent返回视觉父级。
  • children返回视觉儿童。
  • data返回QObject孩子们。

但是我如何访问QObject父级呢?

仅供参考,我打算动态创建和销毁包含自定义类型的嵌套布局,因此我需要管理树QObject- 仅使用可视树将导致“错误”对象在重新设置父级然后删除后消失。

qt qobject qml qt5 qtquick2

6
推荐指数
1
解决办法
4168
查看次数

从基于 QObject 的类继承构造函数

我有一个名为MiscData继承QObject并具有成员变量(模型)的类。然后是一堆继承MiscData并重新实现其虚函数来填充模型的其他类。所以它看起来像这样:

class MiscData : public QObject
{
    Q_OBJECT
public:
    explicit MiscData(QObject *parent = 0);
    QAbstractItemModel &model();
private:
    virtual void loadData() = 0;
private:
    QStandardItemModel m_Model;
}
Run Code Online (Sandbox Code Playgroud)

其中一个后代看起来像这样:

class LogData : public MiscData
{
    Q_OBJECT
public:
    using MiscData::MiscData;
private:
    virtual void loadData() override;
}
Run Code Online (Sandbox Code Playgroud)

我知道我必须使用显式构造函数,MiscData因为它初始化模型成员变量。using但我想知道在派生类中使用指令来继承MiscData这样的构造函数是否安全。

using QObject::QObject编辑:根据答案,在 MiscData 中使用似乎也是很好的事件。

c++ inheritance qt qobject

6
推荐指数
1
解决办法
1万
查看次数

如何将C++属性绑定到QML属性?

所以我知道如何将QML属性绑定到C++属性,所以当C++调用notify信号时,QML会更新视图.当用户使用UI更改内容时,有没有办法使C++属性更新?

例如,我有一个Combobox,我希望在用户更改组合框的值时更新一些C++属性.

编辑:通过C++属性我的意思是Q_PROPERTYQObject来源的类.

c++ qt qobject qml

6
推荐指数
1
解决办法
3108
查看次数