如何删除QSplitter中的所有子项,但保留第一个子项呢?

时间:2019-03-25 17:27:08

标签: c++ qt copy

我有一个自定义类,在其中创建一个QFrame和一个QGrid Layout,其中一个QMainWindow,这个QDockWidget拥有一个{{1} }。现在,我已经掌握了所有这些方法,可以向您展示创建类的感觉。

OpenGLWidget

类RenderView是具有std::unique_ptr<QFrame, std::default_delete<QFrame>> MyProgram::createNewRenderWindow(bool hasFeatures) { QGridLayout *baseLayout = new QGridLayout(); auto newBaseFrame = std::make_unique<QFrame>(new QFrame); auto newRenderView = std::make_unique<RenderView>(hasFeatures); newBaseFrame->setFrameStyle(QFrame::StyledPanel); newBaseFrame->setFrameShadow(QFrame::Sunken); baseLayout->addWidget(newRenderView.release()); newBaseFrame->setLayout(baseLayout); return newBaseFrame; } QMainWindow且拥有QDockWidget的类。然后,将其设置在OpenGLWidgetQFrame中。一旦返回,我通过在构造函数中调用以下命令在gui中对其进行设置:

QGridLayout

在这种情况下,我传递false的原因是因为我的主渲染视图应该在其停靠小部件中未启用任何功能。所以我将此设置为false,因为它是我的主要渲染窗口。创建新的渲染视图时,请将此参数设置为true,以便具有停靠小部件的所有功能。

在我的程序中,我创建了一种创建多个渲染视图的方法,本质上是将渲染视图分为4个不同窗口的能力。但是,主渲染视图始终相同。因此,如果用户想要添加两个以上的窗口,则可以。我通过以下方式做到这一点:

auto mainRenderView = createNewRenderWindow(false);
ui->splitter->addWidget(mainRenderView.release());

然后我将其添加到拆分器中,如下所示:

std::unique_ptr<QSplitter, std::default_delete<QSplitter>> MyProgram::createNewSplitter(Qt::Orientation orientation)
{
    auto newSplitter = std::make_unique<QSplitter>(new QSplitter);
    auto newTopWindow = createNewRenderWindow(true);
    auto newBottomWindow = createNewRenderWindow(true);

    newSplitter->setOrientation(orientation);
    newSplitter->addWidget(newTopWindow.release());
    newSplitter->addWidget(newBottomWindow.release());

    newSplitter->setSizes(QList<int>({HALFRENDERVIEWSIZE, HALFRENDERVIEWSIZE}));

    return newSplitter;
}

这会将主视图分成两部分,然后在右侧的另一个auto newWindows = createNewSplitter(Qt::Vertical); ui->splitter->setOrientation(Qt::Horizontal); ui->splitter->addWidget(newWindows.release()); ui->splitter->setSizes(QList<int>({HALFRENDERVIEWSIZE, HALFRENDERVIEWSIZE})); 中添加两个渲染窗口。好的,现在我已经解释了所有这些(希望很好,程序很大,我不知道如何创建一个最小的示例)。我可以解释真正的问题。

如果需要,我可以从一个渲染视图转到两个,三个或四个。我可以从四个增加到三个或两个。但是,我不能从四比一,三比一或二比一。正如我刚刚链接的帖子所述,这是Copy Constructor的问题。我的第一个想法是从QSplitter中提取主渲染窗口,将其分配给新对象,擦除所有子项,然后将提取的主窗口放回ui->splitter中。但是,尝试快速了解到,一旦从ui->splitter删除了子代,便从提取的主窗口中删除了子代。

ui->splitter

第一个打印语句将打印出2,这表明我已经成功提取了想要的小部件。然后,我打印出 void MyProgram::on_actionOne_View_triggered() { auto mainRenderView = std::move(ui->splitter->widget(MAINRENDERINDEX)); std::cout << mainRenderView.children().count() << " extracted children" << std::endl; std::cout << ui->splitter->children().count() << std::endl; qDeleteAll(ui->splitter->findChildren<QSplitter*>()); std::cout << ui->splitter->children().count() << std::endl; qDeleteAll(ui->splitter->findChildren<QFrame*>()); std::cout << ui->splitter->children().count() <<std::endl; std::cout << mainRenderView.children().count() << " extracted children" << std::endl; ui->splitter->addWidget(mainRenderView.release()); } 拥有的孩子总数。告诉我有四个孩子。然后,我删除所有的ui->splitter并打印出留下QSplitters的数字,即报告还剩两个QFrames。然后,我删除QFrames,并报告返回QFrames中剩余的0个孩子。但是,我然后打印出子ui->splitter并报告0。然后它尝试将提取的小部件插入mainRenderView并由于没有要插入的内容而使程序崩溃。

做到这一点的最佳方法是什么?我曾想过创建自己的复制方法的想法,但是我读过你只是不这样做。无论如何,是否有要删除所有子项并返回到程序启动的起始状态?

0 个答案:

没有答案