Qt小部件不显示时使用std::unique_ptr

Qt Widget not showing when using std::unique_ptr

本文关键字:std unique ptr 小部 显示 Qt      更新时间:2023-10-16

我试图动态地插入一个新的QLabel到我的主窗口。它的工作很好,如果我不使用std::unique_ptr,我可以看到QLabel被绘制在我的窗口。为什么我不能使用std::unique_ptr或std::shared_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();
}

你的代码有两个问题:

std::unique_ptr<QLabel> shrd_QLabel = make_unique<QLabel>();  // 1
shrd_QLabel->setParent(this);                                 // 2
  1. 创建一个智能指针,在作用域结束时释放(当MainWindow的构造函数返回时)
  2. 您将QLabel的所有权分配给MainWindow,因此您的QLabel现在有两个所有者-一个是unique_ptr,第二个是父MainWindow。这是错误的,因为双方都认为他们是唯一的所有者,因此您的Qlabel可能被释放两次。
你的第二个例子是完全有效的。它可以工作,并且没有资源泄漏-您的QLabel将被其父MainWindow释放。注意,不是:
QLabel * lpQLabel = new QLabel();
lpQLabel->setParent(this);

你可以这样做:

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

当您使用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;