2016-06-19 13 views
2

QGridLayoutにテキストを含むQLabelを表示するクラスがあります。 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); 
     lab.setText("RFD"); 
     grid->addWidget(&lab,0,0); //is displayed 
    } 

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はメンバーですか?

+1

スタック上にlabを作成すると、ブロックの最後(つまりctorの最後)ですぐに破棄されます。ヒープ上に作成し、メンバーにする必要があります –

答えて

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 
} 
+0

ありがとうございました! 'グリッド=新しいQGridLayout(この);' ' QLabel *ラボ=新しいQLabel;' ' 、LAB>のsetText( "RFD");' ' グリッド - > addWidget(ラボ、0,0);' 作品。しかし、以前はQtがヒープメモリそのものを扱っていると聞いたのですが、そうではありませんか?またはこの場合、 '* lab'ポインタは削除されますが、ヒープメモリは変更されません。 – parsecer

+2

はい私はあなたが正しいと信じています...しかし、それは常に私の純粋なC++の背景から漏れのように感じます:o –

+1

@parsecer:QLabelに親を与えると、 ''新しいQLabel(this) '、' this'が破壊された場合、Qtはあなたのためにそれをクリーンアップします。これを明示的に行う必要がある場合は、https://doc.qt.io/qt-5/qobject.html#setParentも参照してください。 – Bugfinger

1

QLabel lab;は、関数の最後まで住んでいるローカル変数で、自動的に破棄されるので、表示したいラベルは表示したいときにはもはや実際には存在しません。

はさらに、Qtはあり壊れQLabelアップnewにあなたを必要とし、その後、Qtは自動的delete後で親が削除されるだろう機能を所有している生のポインタを渡すことmemory model型破り。 deleteの場合、手動でダブルdelete(1つはあなたともう1つはQt)になり、通常はクラッシュします。手作業でオブジェクトを挿入すると、自動的に親からそれが切り離されるため、ダブルdeleteが得られません。

これはメモリリークのように見えますがQtは、あなたがそれをやりたい道が

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

であることは、それは、Qtのメモリモデルによるものではありません。

+0

ありがとうございました。 – parsecer

+0

これは完全に真実ではありません。指定したリンクに記載されているように、親より前にオブジェクトを削除すると、二重削除されません。オブジェクトが破棄されると、それらは親から削除されます。親によって既に破壊された後で自分自身を削除しようとすると、二重削除だけが得られます。また、 'new'を使用するよう強制しません。 'new'を使わない場合は、定義順に注意するだけです。しかし、それ以外のあなたの答えは正しいです。 – thuga

+0

@thugaもっと詳しく説明できますか? Qtはあなたがオブジェクトを削除したかどうかを知ることができません。あなたができることはQtから所有権を取り戻し、手動で削除することです。また、 'new'で作成されていないポインタをQtに与えて、親が消える前に所有権を取り戻すことができます。 – nwp

関連する問題