我有一个自定义类,在其中创建一个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
的类。然后,将其设置在OpenGLWidget
和QFrame
中。一旦返回,我通过在构造函数中调用以下命令在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
并由于没有要插入的内容而使程序崩溃。
做到这一点的最佳方法是什么?我曾想过创建自己的复制方法的想法,但是我读过你只是不这样做。无论如何,是否有要删除所有子项并返回到程序启动的起始状态?