Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ну и что-же мне делать с этой чертовой сценой?
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Система рисования. Печать
Strikevld
Хоть убей не гугл не документация не в помощь!
Идея такая: есть сцена. есть собственный виджет построенный в дизайнере. экземпляры этого виджета должны динамически создаваться(также добавляясь на сцену) и удаляться. всё это по требаванию пользователя!

Но вот такая штука они создаются,,, и показываются,,, ии удаляются если не в сцене!
стоит только добавить виджет в сцену и всё его хрен удалишь!
Причем хоть как хоть как:
ни тебе удаляя со сцены, и даже удаляя саму сцену, ни delete wgt, ни wgt.deleteLater()
отладчик не помогает

вот код:
void SSMain::getDevices()
{
    // devicesList - это QList<DewiceWidget*>
    // DeviceWidget - это сам виджет созданный в дизайнере содержащий в себе другие виджеты
    if (devicesList.size() > 0) {
        scene->clear();
        delete  scene;
        for(int i = 0; i < devicesList.size(); i++) {
            delete devicesList[i]; // удаляем каждый виджет
        }
        devicesList.clear();  // чистим список
    }


    scene = new QGraphicsScene(this);
    ui->graphicsViewDevices->setScene(scene);
    QString devsPath = QDir::currentPath() + "/Devices";
    QDir dir(devsPath);
    QStringList l = dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot);

    foreach(QString str, l) {
        QDir td(devsPath + "/" + str);
        QStringList tsl = td.entryList(QStringList("*.ini"), QDir::Files);
        foreach(QString xstr, tsl) {
            QString tinifile = devsPath + "/" + str + "/" + xstr;
            QSettings tsetfile(tinifile, QSettings::IniFormat);
            if (!tsetfile.value("General/ThisFileDeviceInfo", false).toBool())
                continue;

            devicesList.append(new DeviceWidget());
            //devicesList[devicesList.size() - 1]->setAttribute(Qt::WA_DeleteOnClose);   // это я и так пытался сделать, а там выше делал devicesList[i].close;
            scene->addWidget(devicesList[devicesList.size() - 1]); // вот если этого не делать то виджеты нормально удаляются из памяти <<<<<<<<<
            devicesList[devicesList.size() - 1]->move(140 * (devicesList.size() - 1), 0);
        }
    }

}


на delete и возникает неуловимое исключение, только если эти виджеты в сцене, причём пока я их не пытаюсь удалить всё нормально.
(я уже подумываю так и осталять их в памяти :lol: )

Что не так то???
Помогите.
Авварон
Цитата(Strikevld @ 2.1.2013, 1:46) *
Хоть убей не гугл не документация не в помощь!
Идея такая: есть сцена. есть собственный виджет построенный в дизайнере. экземпляры этого виджета должны динамически создаваться(также добавляясь на сцену) и удаляться. всё это по требаванию пользователя!

Но вот такая штука они создаются,,, и показываются,,, ии удаляются если не в сцене!
стоит только добавить виджет в сцену и всё его хрен удалишь!
Причем хоть как хоть как:
ни тебе удаляя со сцены, и даже удаляя саму сцену, ни delete wgt, ни wgt.deleteLater()
отладчик не помогает

вот код:
void SSMain::getDevices()
{
    // devicesList - это QList<DewiceWidget*>
    // DeviceWidget - это сам виджет созданный в дизайнере содержащий в себе другие виджеты
    if (devicesList.size() > 0) {
        scene->clear();
        delete  scene;
        for(int i = 0; i < devicesList.size(); i++) {
            delete devicesList[i]; // удаляем каждый виджет
        }
        devicesList.clear();  // чистим список
    }


    scene = new QGraphicsScene(this);
    ui->graphicsViewDevices->setScene(scene);
    QString devsPath = QDir::currentPath() + "/Devices";
    QDir dir(devsPath);
    QStringList l = dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot);

    foreach(QString str, l) {
        QDir td(devsPath + "/" + str);
        QStringList tsl = td.entryList(QStringList("*.ini"), QDir::Files);
        foreach(QString xstr, tsl) {
            QString tinifile = devsPath + "/" + str + "/" + xstr;
            QSettings tsetfile(tinifile, QSettings::IniFormat);
            if (!tsetfile.value("General/ThisFileDeviceInfo", false).toBool())
                continue;

            devicesList.append(new DeviceWidget());
            //devicesList[devicesList.size() - 1]->setAttribute(Qt::WA_DeleteOnClose);   // это я и так пытался сделать, а там выше делал devicesList[i].close;
            scene->addWidget(devicesList[devicesList.size() - 1]); // вот если этого не делать то виджеты нормально удаляются из памяти <<<<<<<<<
            devicesList[devicesList.size() - 1]->move(140 * (devicesList.size() - 1), 0);
        }
    }

}


на delete и возникает неуловимое исключение, только если эти виджеты в сцене, причём пока я их не пытаюсь удалить всё нормально.
(я уже подумываю так и осталять их в памяти :lol: )

Что не так то???
Помогите.


При удалении сцена удаляет все, что в нее добавлено, в тч ваши виджеты. Получается, что вы их удаляете дважды. Вообще, размещать виджеты на сцене-не самая здравая идея, так как там не обернешься багов с прокси айтемом. Вам точно нужна сцена? Может можно обойтись кастомным лэйаутом?
Strikevld
Да именно сцена. (на ней не только виджеты будут)

Хм.. дак ведь если сцену не удалять то при удалении виджетов точно тот же самый баг.
И кстати проверил. при удалении сцены виджеты не удаляются.(т.е. нет "access violation" при доступе к членам класса, т.е. я в мсгбоксе вывел текст одного из лейблов на виджете который был на сцене)

Хотя я не очень понял "с кастомным лайоутом". Натолкните на мысль! Посмотрю можно ли заменить сцену на него!
Авварон
Конкретно удалять виджеты должна эта
 scene->clear();

строка.

То, что к полям виджета есть доступ ни о чем не говорит - память еще могла быть не использована, но уже отмечена как свободная.

Попробуйте поставить бряку в деструктор виджета или вставить отладочную печать. А еще можно использовать QPointer'ы в списке для теста (и проверить их на 0 после очистки сцены).

Насчет лайаута - я же не знаю, что вам надо:) Если помимо виджетов будут айтемы, то сцена нужна. Но тогда гораздо более прямым способом будет переписать виджеты на графиксайтемы или использовать qml. Можно в сторону mdi посмотреть ещё.
Strikevld
Ухты! Благодарю за помощь! И правда всё разрушается при scene->clear();

На Qml то у меня и так этот Gui забахан уже, там проще. Но прога будет на слабых компах тоже использоваться! (Граф.интерфейс меняется динамически)

Ладно! Всё клёво работает! Спасибо :) :) :)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.