【问题标题】:In QT, how to remove child widget from parent after receiving the signal generated by child?QT中,接收到child产生的信号后如何从parent中移除child widget?
【发布时间】:2018-04-29 04:05:00
【问题描述】:

QT中,接收到child产生的信号后如何将child widget从parent中移除?

我正在使用 QT 5.7 并使用 2 个小部件 view1 和 view2 编写一个简单的程序。 view1里面有一个名为“btn_1”的按钮,view2里面有一个名为“btn_leave”的按钮。

当你点击“btn_1”时,它会生成一个view2对象并将它添加到view1的布局中。我希望在单击“btn_leave”时删除 view2。

这是我的想法。在 view2 中单击 leave_btn 时,它会发出一个名为“leave”的信号。我将此信号连接到 lambda 函数以删除 view2。

void VIEW1::on_btn_1_clicked() {
    VIEW2 *view2 = new VIEW2();
    layout->addWidget(view2);

    connect(view2, &VIEW2::leave, this, [&view2]() {
        delete view2;
    });
}

程序崩溃并不奇怪,因为我在 view2 发出信号时删除了 view2。 view2 可以在发出离开信号后访问它的成员。

所以我用 deleteLater 重写它。根据QT文档,当控制返回事件循环时,该对象将被删除。

void VIEW1::on_btn_1_clicked() {
    VIEW2 *view2 = new VIEW2();
    layout->addWidget(view2);

    connect(view2, &VIEW2::leave, this, [&view2]() {
        view2.deleteLater();
    });
}

但令人惊讶的是,程序又崩溃了。是不是我对 deleteLater 的使用有什么误解,或者在调用 deletelater() 之后事件队列访问 view2 中仍然有一些事件?

如果有帮助,我已将我的整个程序(使用 QT 创建者创建)上传到 github

【问题讨论】:

    标签: c++ qt qt5 qt-signals


    【解决方案1】:

    你必须传递view2的指针,而不是指针的指针,除了this之外没有必要。

    void VIEW1::on_btn_1_clicked() {
        VIEW2 *view2 = new VIEW2();
        layout->addWidget(view2);
    
        connect(view2, &VIEW2::leave, [view2]() {
            view2->deleteLater();
        });
    }
    

    或者干脆不使用 lambda 函数,而是使用 new connection style:

    void VIEW1::on_btn_1_clicked() {
        VIEW2 *view2 = new VIEW2();
        layout->addWidget(view2);
        connect(view2, &VIEW2::leave, view2, &VIEW2::deleteLater);
    }
    

    另一种选择是不创建leave信号,并建立点击信号的连接

    VIEW2::VIEW2(QWidget *parent) :
        QWidget(parent)
    {
        label = new QLabel(this);
        label->setText("view2");
        btn_leave = new QPushButton(this);
        btn_leave->setText("leave");
    
        layout = new QHBoxLayout;
        layout->addWidget(label);
        layout->addWidget(btn_leave);
        setLayout(layout);
    
        connect(btn_leave, &QAbstractButton::clicked, this, &VIEW2::deleteLater);
    }
    

    【讨论】:

    • 感谢@eyllanesc,您提供了几个有用的连接使用示例。我想知道 connect(view2, &VIEW2::leave, this, [view2]() { delete view2; });运行也很好,是不是很幸运,我仍然必须使用 deletLater() 进行最佳实践?
    • @Opass deleteLater 是最佳实践。阅读stackoverflow.com/questions/4888189/…
    猜你喜欢
    • 2016-03-22
    • 2020-05-07
    • 2018-03-12
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多