Премахване на QWidgets от QGridLayout

Имам QGridLayout, където добавям своя персонализиран QWidgets.

Когато се опитам да изтрия всички от тях, те се предполага, че са премахнати от оформлението (тъй като функцията layout.count() връща 0), но те все още се показват в интерфейса и мога да взаимодействам с тях.

Ето начина, по който добавям джаджи:

void MyClass::addCustomWidget(CustomWidget *_widget, int r, int c)
{
    layout->addWidget(_widget, r, c);
    _widget->show();
}

И ето начина, по който ги изтривам:

void MyClass::clearLayout()
{
    qDebug() << "Layout count before clearing it: " << layout->count();

    int count = layout->count();
    int colums = layout->columnCount();
    int rows = layout->rowCount();

    int i=0;
    for(int j=0; j<rows; j++)
    {
        for(int k=0; k<colums && i<count; k++)
        {
            i++;

            qDebug() << "Removing item at: " << j << "," << k;
            QLayoutItem* item = layout->itemAtPosition(j, k);

            if (!item) continue;

            if (item->widget()) {
                layout->removeWidget(item->widget());
            } else {
                layout->removeItem(item);
            }
            qDebug() << "Removed!";
        }
    }

    qDebug() << "Layout count after clearing it: " << layout->count();
}

Някакъв вид помощ или съвет за правилно изтриване на елементи/приспособления от QGridLayout?

P.D. : Виждал съм в интернет, че много хора изтриват джаджата директно (delete _widget), след като са ги премахнали от оформлението. В моя случай не е възможно, тъй като трябва да поддържам тези джаджи в паметта.


person azorrozua    schedule 23.05.2012    source източник
comment
възможен дубликат на Премахване на приспособления от QGridLayout   -  person emkey08    schedule 09.10.2013


Отговори (4)


Само за да е ясно. Не сте "изтрили" джаджите. Премахнахте ги само от оформлението. Премахването от оформлението означава само, че приспособлението няма повече да се управлява (преоразмерява/позиционира) от това оформление, НО това не означава, че приспособлението ще бъде „изтрито“ (по C++ начин). Освен това джаджата няма да бъде магически скрита. Вашата джаджа след премахване от оформлението все още остава в джаджа, в която е създадена/управлявана. Така че собственикът на това оформление все още има тази джаджа като дете (видимо дете).

Ти трябва да

  1. скриване на джаджа или ако сте сигурни, че няма да се използва повече

  2. изтриване на джаджа с ключова дума „изтриване“.

Също така не е необходимо да се обаждате на removeWidget(item->widget()); removeItem(item) ще бъде достатъчно за всички елементи на оформлението (дори тези с джаджа вътре)

person Kamil Klimek    schedule 23.05.2012
comment
Моето намерение е да премахна джаджите от оформлението (и да не ги показвам повече), но да ги поддържам в паметта. Опитах се да скрия джаджите (_widget.hide), преди да ги премахна от оформлението и се получи, благодаря. - person azorrozua; 23.05.2012

Опитвам

QLayoutItem *child;
while ((child = layout->takeAt(0)) != 0);

Той трябва да е безопасен. Ако по някаква причина не работи, можете да използвате колекция от джаджи или елементи на оформление, които се актуализират всеки път, когато добавите джаджа. След това, за да изтриете, правите цикъл на колекцията и премахвате всеки елемент от оформлението.

person UmNyobe    schedule 23.05.2012

Можете също да използвате deleteLater(), за да избегнете проблеми с поддържането на броя на децата по време на итерации:

for (int i = 0; i < gridLayout.count(); i++)
{
   gridLayout.itemAt(i)->widget()->deleteLater();
}
person vdudouyt    schedule 12.03.2017
comment
Благодаря, че се опитахте да разрешите проблема 5 години по-късно ;) - person azorrozua; 13.03.2017

Нито един от тези отговори не ми помогна. В моята ситуация имам няколко обекта, всеки със собствен QChartView. Идеята е, че потребителят избира кой обект иска да види и централна обща област в главния прозорец се актуализира с QChartView на избрания от потребителя обект. Това трябваше да е лесно, просто премахнете джаджата от областта на диаграмата, добавете нова. Това, което в крайна сметка работи за мен, беше следното:

while( QLayoutItem* item = ui->mPlotArea->layout()->takeAt(0) )
{
    item->widget()->setVisible(false);
    ui->mPlotArea->layout()->removeItem(item);
}

ui->mPlotArea->layout()->addWidget( pv );
pv->setVisible(true);

Където mPlotArea е QFrame, а pv е производен клас на QChartView. Не мога да обясня защо другите отговори не проработиха, но прекарах няколко часа в изпробване на различни джаджи и различни начини за премахване без изтриване, организиране и т.н.

person Alex Baum    schedule 01.10.2020