QT:以正确的方式设置我自己的Qwidget
-
22-09-2019 - |
题
在QT中,我试图设置自己的Qwidget,以便由于内存管理和其他内容,一切都应该很好地工作。但是,我似乎无法通过指针,堆和堆栈才能得到一切。我的小部件mywidget具有带有一些对象的Qlist。我不知道如何正确设置所有内容。
您可以在下面看到我的代码,我对此有一些疑问:
即时变量列表是在堆上创建的,最好在堆栈上创建它吗?
在我的列表中,我有指针,最好只在堆栈上创建对象并将其附加到列表中吗? (这样我根本没有指针)
当我将对象附加到列表中时,他们会自动将列表作为父母自动获取吗?因此,当我删除列表时,列表中的所有对象将被删除?
我要使用的每个循环不起作用,我得到了“预期该操作的指针/数组类型,而不是'int'”
在我的代码中,我想创建其他将对象从列表中作为参数获取的小部件。这是正确的方法吗? Myotherwidget的实例方法看起来像:myotherwidget(myObject *myObject,qwidget *parent)
谢谢你的帮助!我是QT和C ++的新手,所以如果您可以指导我朝正确的方向引导我,那就太好了。如何以正确的方式设置此设置,以使其变得简单,不要获得内存泄漏并根据需要使用尽可能少的内存。您将如何设置同一件事?
这是我的代码:
mywidget.h:
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget *parent = 0);
~MyWidget();
private:
QList<MyObject*> *list;
};
mywidget.cpp:
MyWidget::MyWidget(QWidget *parent)
{
ui.setupUi(this);
list = new QList<MyObject*>();
for (int i = 0; i<10; i++)
{
MyObject *myObject = new MyObject("Hello",this);
list->append(myObject);
}
foreach(MyObject *myObject, list)
{
//Lets say I want to create other widgets here and that they takes a MyObject as a parameter
MyOtherWidget *myOtherWidget = new MyOtherWidget(myObject,this);
}
}
MyWidget::~MyWidget(){
delete list;
}
解决方案
AD.1。列表的寿命应与MyWidget实例的寿命相同,因此您可以在堆栈上安全地创建列表。
AD.2。您可以做到这一点,但是MyObject类需要具有默认构造函数,复制构造函数和一个分配运算符(请参阅 http://doc.trolltech.com/4.6/containers.html#container-classes 有关详细信息)。
AD.3。对象的所有权未在附加内容上转移。就像STL容器一样,QT容器不会在存储的指针上调用DELETE。要删除存储在Qlist(或其他QT容器)中的所有指针,您可以使用QDeleteAll(列表)。请注意,您可能不想在发布的代码中这样做:您将myWidget指针传递给myObject构造函数,我认为它然后用作qobject parent。因此,当MyWidget删除时,所有QOBjects都将被删除。
AD.4。 foreach宏的第二个论点应该是一个容器,而不是指针到容器。因此,如果您的列表变量是Qlist的指针,则应致电foreach(myObject *obj, *list)。
AD.5。只要MyotherWidget不删除传递的MyObject(因为MyWidget已经是MyObject的父,并且您最终将同一对象删除同一对象)。
这是一个简单的简化,但是您应该尝试以完全不需要调用DELETE的方式编写代码。在堆栈上创建东西或依靠QT父母机制(即父母删除孩子)。稍后,您可能需要阅读有关智能指针(QSHAREDPOINTER,QSCOPEDPOINTER等)的信息。
编辑:
MyObject的父级设置是否取决于您在MyObject构造函数中所做的事情。如果您将父级参数传递给qobject构造函数,即您的myObject构造函数看起来像这样:
MyObject(const QString &text, QObject *parent = 0) : QObject(parent)
{
// more code...
}
将设置父,因为它将在qobject构造器中完成,该代码将被称为“:qObject(parent)”代码。如果您没有这个碎片怎么办?由于MyObject继承了qObject,并且您不指定哪个构造函数应称为默认的qObject构造函数,即qobject(qObject *parent *parent = 0),因此您的myObject的父级将是null的,并且不会为删除。
我会尽量避免通过setparent方法明确设置父 - 对于基本用例,在构造函数中设置parent应该足够。
尝试使用正确的术语(不是“实例方法”,而是“构造函数”),读取QT文档,使用常识,并尽量不要以为会自动完成任何操作。父母不是仅仅因为您调用一个参数“ parent”的“自动”设置 - 它是设置的,因为有一块代码在qobject构造函数中执行此操作,并且您有责任将适当的parth pass pass pass pass pass pasth parth to Chonstort在类中继承Qobject。
其他提示
是的,问题在于您要删除列表的对象,而不是其元素!
我建议您看看:
QList<Employee *> list;
list.append(new Employee("Blackpool", "Stephen"));
list.append(new Employee("Twist", "Oliver"));
qDeleteAll(list.begin(), list.end());
list.clear();
我还会问您是否真的需要指向列表的指针?您可以简单地简单:
QList<MyObject*> list;
因此,您的内存泄漏较少!
希望这个对你有帮助 !
编辑 :
3.您的MyObject对象作为父母具有“此”。当您处理指针时,该列表不会占用对象。
4.对于循环,也许您应该考虑迭代器,在这里看看 qthelp://com.trolltech.qt.460/qdoc/qlist.html.
只要您使它们成为当前小部件的父母,您就无需将儿童小部件存储在列表中。 (通常,您可以在堆栈上使用New创建小部件)。
QT具有自动清洁函数,这意味着,如果删除了小部件,则所有子小部件(父母是被删除的小部件的小部件)被删除。
因此,您唯一必须确保(尤其是对于临时弹出窗口小部件)删除/删除小部件“弹出窗口”或调用弹出窗口小部件的唯一一件事。
就是这样。