首页 > 解决方案 > Qt widget析构函数通过connected信号间接调用widget方法,并崩溃

问题描述

我基于 制作了一个小部件(QDataflowCanvas)QGraphicsView,在其中将信号连接QGraphicsScene::selectionChanged()到主窗口的插槽MainWindow::onSelectionChanged

void MainWindow::onSelectionChanged()
{
    // canvas is ptr to QDataflowCanvas, subclass of QGraphicsView
    auto selNodes = canvas->selectedNodes();
    auto selConns = canvas->selectedConnections();
    ...
}

当我关闭我的MainWindow并且在QGraphicsView.

我认为我不需要提供完整的代码(尽管可以在此处找到),因为我已经隔离了崩溃的原因。

这就是将会发生的事情(按因果顺序):

从崩溃的堆栈跟踪中可以更详细地看到:

来自 Qt Creator 的堆栈跟踪

我找到了这个解决方法:如果我断开信号MainWindow::~MainWindow,它当然不会崩溃:

MainWindow::~MainWindow()
{
    QObject::disconnect(canvas->scene(), &QGraphicsScene::selectionChanged, this, &MainWindow::onSelectionChanged);
}

但这似乎是一种相当不典型的做法:我从来没有发现自己必须手动进行严重的信号槽连接,否则程序会崩溃。

必须有一个更合适的解决方案。

标签: c++qt

解决方案


canvas我把它看得太简单了:) 只检查指针怎么样:

void MainWindow::onSelectionChanged()
{
    if (!qobject_cast<QGraphicsScene*>(canvas))
        return;

    auto selNodes = canvas->selectedNodes();
    auto selConns = canvas->selectedConnections();
    ...
}

我曾经qobject_cast检查指针是否canvas仍然存在。您可以以其他(更好的)方式进行检查。该代码有效。


推荐阅读