У меня есть пользовательский класс, в котором я создаю QFrame
с QGrid Layout
, который имеет QMainWindow
, который имеет QDockWidget
, которому принадлежит OpenGLWidget
.Теперь, когда у меня есть все это, я могу показать вам, каково это создавать класс.
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;
}
Класс RenderView - это класс, который имеет QMainWindow
с QDockWidget
, которому принадлежит OpenGLWidget
.Затем я устанавливаю это в QFrame
с QGridLayout
.Когда это возвращается, я установил его в своем графическом интерфейсе, вызвав в конструкторе следующее:
auto mainRenderView = createNewRenderWindow(false);
ui->splitter->addWidget(mainRenderView.release());
Причина, по которой в этом случае я передаю false, заключается в том, что в моем основном представлении рендеринга не должно быть никаких включенных функций.в доке виджет.Поэтому я установил для этого значение false, потому что это мое главное окно рендеринга.Когда я создаю новый вид рендеринга, я устанавливаю для этого аргумента значение true, чтобы у меня были все возможности виджета дока.
В моей программе я создал способ создания более одного вида рендеринга, по сути, возможность разбить вид рендеринга на 4 разных окна.Тем не менее, основной вид рендеринга всегда одинаков.Так что, если пользователь хочет добавить еще два окна, он может.Я делаю это следующим образом:
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}));
Это разделит основной вид пополам, а затем добавит два рендера.окна на правой стороне в другом QSplitter
.Хорошо, теперь, когда я объяснил все это (надеюсь, достаточно хорошо, программа огромна, и я не знаю, как создать минимальный пример этого).Я могу объяснить реальную проблему.
Я могу перейти от одного вида рендеринга к двум, или к трем, или к четырем, если захочу.Я могу пойти с четырех до трех или двух.Однако я не могу перейти от четырех к одному, от трех до одного или от двух до одного.И это проблема с Copy Constructor , как указано в посте, который я только что связал.Моей первой идеей было извлечь главное окно рендеринга из ui->splitter
, назначить его новому объекту, стереть все дочерние элементы и поместить извлеченное главное окно обратно в ui->splitter
.Однако, пытаясь быстро узнать, что, удаляя потомков из ui->splitter
, я удаляю потомков из извлеченного главного окна.
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());
}
Первый оператор print выведет 2, что говорит мнечто я успешно извлек виджет, который я хотел.Затем я распечатываю общее количество детей, которое имеет ui->splitter
.Который говорит мне, что у него есть 4 детей.Затем я удаляю все QSplitters
и распечатываю число, которое оставляет QFrames
, что сообщает, что осталось два QFrames
.Затем я удаляю QFrames
, и он сообщает, что в ui->splitter
осталось 0 детей.Однако затем я распечатываю дочерние элементы, которые есть у mainRenderView
, и возвращает 0. Затем он пытается вставить извлеченный виджет в ui->splitter
и вылетает из программы, поскольку вставлять нечего.
Каков наилучший способ сделать это?Я играл с идеей создания собственного метода копирования, однако я читал, что вы просто не делаете этого.Есть ли способ удалить все дочерние элементы и вернуться в исходное состояние, в котором запускается программа?