Как удалить всех потомков в QSplitter, но удержать первого потомка? - PullRequest
1 голос
/ 25 марта 2019

У меня есть пользовательский класс, в котором я создаю 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 и вылетает из программы, поскольку вставлять нечего.

Каков наилучший способ сделать это?Я играл с идеей создания собственного метода копирования, однако я читал, что вы просто не делаете этого.Есть ли способ удалить все дочерние элементы и вернуться в исходное состояние, в котором запускается программа?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...