如果不是会员,QLabel不会显示

时间:2016-06-19 14:51:44

标签: c++ qt

我有一个类在QGridLayout中显示QLabel和一些文本。当QLabel是班级成员时,一切正常,但如果不是,则不会在网格中显示。

QLabel不是成员,而是在构造函数中创建的。

class Account : public QWidget
    {
    private:
       //QLabel lab;
        QGridLayout * grid;
          public:
        Account(QWidget * parent=0);

    public slots:
        void spend(int);
        void update();

    };

的.cpp

#include <QLabel>
    #include <QLineEdit>
    #include <QTextStream>
#include <QFileInfo>
#include <vector>
#include <QGridLayout>
#include <iostream>

Account::Account(QWidget * parent) : QWidget(parent)
{

    grid=new QGridLayout(this);
    QLabel lab;
    lab.setText("RFD");
    grid->addWidget(&lab,0,0); //is not displayed
}

QLabel是会员:

  class Account : public QWidget
    {
    private:
       QLabel lab;
        QGridLayout * grid;
          public:
        Account(QWidget * parent=0);

    public slots:
        void spend(int);
        void update();

    };

.cpp

#include <QLabel>
    #include <QLineEdit>
    #include <QTextStream>
    #include <QFileInfo>
    #include <vector>
    #include <QGridLayout>
    #include <iostream>

    Account::Account(QWidget * parent) : QWidget(parent)
    {

        grid=new QGridLayout(this);
        lab.setText("RFD");
        grid->addWidget(&lab,0,0); //is displayed
    }

为什么会这样?

2 个答案:

答案 0 :(得分:3)

因为当你在构造函数中声明QLabel时它只是一个局部变量,因此它在函数末尾超出范围(参见下面的评论):

{
    grid=new QGridLayout(this);
    QLabel lab; // created here
    lab.setText("RFD");
    grid->addWidget(&lab,0,0); //is not displayed
} // destroyed here as the variable is out of scope

注意

如果你想在你的构造函数中创建它然后使它成为一个指针并且它是新的 - 你仍然需要跟踪这个指针,作为成员变量或将指针传递给其他一些函数/类来照顾它...(即当你完成它时删除它......

此外 - addWidget()接受一个指针,因此它可能会处理它本身的破坏 - 所以你可能会这样做:

{
    grid=new QGridLayout(this);
    QLabel *pLab = new QLabel(this);
    lab.setText("RFD");
    grid->addWidget(pLab,0,0); //is not displayed
}

答案 1 :(得分:1)

QLabel lab;是一个局部变量,一直存在,直到函数结束,然后被自动销毁,因此当你想要显示它时,你想要显示的标签就不再存在了。

此外,Qt有破解非常规memory model,要求你new向上QLabel,然后将拥有的原始指针传递给Qt将执行的函数父母被删除后自动delete如果你手动delete,你会得到一个双delete(一个来自你,一个来自Qt),这通常会导致崩溃。手动delete一个对象会自动将其与父母分开,因此您不会获得双倍delete

Qt希望你这样做的方式是

QLabel *lab = new QLabel;
lab->setText("RFD");
grid->addWidget(lab,0,0);

虽然这看起来像是内存泄漏,但由于Qt的内存模型,它不是。