2015-09-28 246 views
0

我想动态地将一个新的QLabel插入到我的主窗口。它工作正常,如果我不使用std :: unique_ptr,我可以看到在我的窗口绘制QLabel。为什么我不能使用std :: unique_ptr或std :: shared_ptr?Qt Widget使用std :: unique_ptr时不显示

MainWindow::MainWindow(QWidget *parent):QMainWindow(parent) 
{ 

setWindowFlags(Qt::FramelessWindowHint); 
ui.setupUi(this); 

std::unique_ptr<QLabel> shrd_QLabel = make_unique<QLabel>(); 
shrd_QLabel->setParent(this); 
shrd_QLabel->setText("test"); 
shrd_QLabel->setGeometry(70, 70, 70, 70); 
shrd_QLabel->show(); 
//The above doesnt work, however, below example works perfectly 

QLabel * lpQLabel = new QLabel(); 
lpQLabel->setParent(this); 
lpQLabel->setText("TEST #2"); 
lpQLabel->setGeometry(70, 170, 70, 70); 
lpQLabel->show(); 
} 
+2

你不是真的“自己的”小部件,窗口呢,它会处理widget的所有生命周期管理包括在窗户被毁坏时确保它被销毁。这就是所有这些亲子关系都是关于这里的。因此,不需要新的智能指针,它们有自己独立的生命周期管理,在这种情况下与Qt中的指针发生冲突。 –

+0

请不要使用'QMainWindow'。只需从'QWidget'派生。 'QMainWindow'提供了特定的对接功能 - 如果你不使用它,你不需要'QMainWindow'。 –

回答

2

当您使用std::unique_ptr,对象在范围结束时删除,所以它就像你这样做:

QLabel *shrd_QLabel = new QLabel; 
shrd_QLabel->setParent(this); 
shrd_QLabel->setText("test"); 
shrd_QLabel->setGeometry(70, 70, 70, 70); 
shrd_QLabel->show(); 
delete shrd_QLabel; 
3

您的代码有两个问题:

std::unique_ptr<QLabel> shrd_QLabel = make_unique<QLabel>(); // 1 
shrd_QLabel->setParent(this);         // 2 
  1. 您创建一个在作用域结束时释放的智能指针(当MainWindow的构造函数返回时)
  2. 您将QLabel指定为ownershipMainWindow,因此您的QLabel现在有两位所有者 - 一位是unique_ptr,第二位是家长MainWindow。这是错误的,因为双方都认为他们是唯一的所有者,因此您的Qlabel可能会被释放两次。

你的第二个例子是完全有效的。它的工作,并没有资源泄漏 - 您的QLabel将被其母公司MainWindow释放。请注意,而不是:

QLabel * lpQLabel = new QLabel(); 
lpQLabel->setParent(this); 

你可以这样做:

QLabel * lpQLabel = new QLabel(this); // lpQLabel is owned by `this`