Russian Qt Forum
Май 06, 2024, 05:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QDialog + QLayout Ошибка  (Прочитано 3407 раз)
SlimSlot
Гость
« : Август 02, 2011, 12:34 »

Добрый день!

Есть класс, унаследованный от QDialog
В конструкторе создается QGridLayout, который устанавливается this->setLayout(p_GridLayout)
Далее вызывается функция

Код:
    QComboBox* l_pComboBox_Field = new QComboBox();
    QComboBox* l_pComboBox_TypeLimit = new QComboBox();
    QLineEdit* l_pLineEdit_ValueLimit = new QLineEdit();
    QHBoxLayout* l_pHBoxLayout_LimitLine = new QHBoxLayout();

    l_pHBoxLayout_LimitLine->addWidget(l_pComboBox_Field);
    l_pHBoxLayout_LimitLine->addWidget(l_pComboBox_TypeLimit);
    l_pHBoxLayout_LimitLine->addWidget(l_pLineEdit_ValueLimit);

    l_pComboBox_Field->addItem("");
    for (int i = 0; i < p_SqlModel->columnCount(); i++)
        l_pComboBox_Field->addItem(p_SqlModel->headerData(i, Qt::Horizontal).toString());

    connect(l_pComboBox_Field, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_SelectFilterColumn(QString)));

    p_GridLayout->addLayout(l_pHBoxLayout_LimitLine, iCountLimitLines, 0, 1, 3);

    iCountLimitLines++;

Суть в чем. При определенных действиях добавляется строка в GridLayout в виде HBoxLayout динамически.

Сам диалог создается из другого окна QMainWindow

Код:
Limit* l_pLimit = new Limit(p_User, p_Model);

    l_pLimit->setModal(true);
    l_pLimit->exec();

При запуске вылезает ошибка
Цитировать
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Runtime Error!

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Попробовал поотлаживать.
Валится где-то на месте, связанным с layout в какой-то структуре, где сам layout как я понимаю не инициализирован и разыменывание приводит к краху.

Не могу понять в чем ошибка. Помогите пожалуйста, хоть в какую сторону смотреть.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Август 02, 2011, 13:43 »

Цитировать
В конструкторе создается QGridLayout, который устанавливается this->setLayout(p_GridLayout)
Ну дык и где ентот конструктор?
Записан

Qt 5.11/4.8.7 (X11/Win)
SlimSlot
Гость
« Ответ #2 : Август 02, 2011, 13:49 »

Цитировать
В конструкторе создается QGridLayout, который устанавливается this->setLayout(p_GridLayout)
Ну дык и где ентот конструктор?
А, да, забыл конструктор.
Вот же он

Код:
Limit::Limit(LoginUser* user, QSqlQueryModel* model, QWidget *parent): QDialog(parent)

{
    p_user = user;
    p_SqlModel = model;
    p_GridLayout = new QGridLayout();
    this->setLayout(p_GridLayout);
    CreateUI();
}

где user - это объект, класс которого унаследован от QObject
в CreateUI вызывается моя функция AddLimitLine:

Код:
QLabel* l_pLable_Information = new QLabel("тратата");
    QPushButton* l_pBtn_OK = new QPushButton("ОК");
    QPushButton* l_pBtn_Cancle = new QPushButton("Отмена");
    QPushButton* l_pBtn_AddLimitLine = new QPushButton("Добавить строку ограничения");
    QVBoxLayout* l_pVBoxLayout_OkCancle = new QVBoxLayout();



    l_pVBoxLayout_OkCancle->addWidget(l_pBtn_OK);
    l_pVBoxLayout_OkCancle->addWidget(l_pBtn_Cancle);

    p_GridLayout->addLayout(l_pVBoxLayout_OkCancle, 0, 4, 2, 1);
    p_GridLayout->addWidget(l_pBtn_AddLimitLine, 1, 0, 1, 1);
    p_GridLayout->addWidget(l_pLable_Information, 0, 0, 1, 1);
    AddLimitLine();


Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Август 02, 2011, 14:05 »

где инициализация iCountLimitLines?
Записан

Qt 5.11/4.8.7 (X11/Win)
SlimSlot
Гость
« Ответ #4 : Август 02, 2011, 14:32 »

Вот черт.
Теперь понял почему так произошло.
Спасибо огромное!!!!
Записан
SlimSlot
Гость
« Ответ #5 : Август 03, 2011, 17:25 »

В продолжение темы...
Добавление строки фильтра я сделал.
Теперь удаление строки фильтра
Вот  код указанного ранее слота slot_SelectFilterColumn
Код:
void Limit::slot_SelectFilterColumn(QString ColumnName)
{
    if (sender()->objectName().toInt() == iCountLimitLines-1)
        AddLimitLine();

    if (ColumnName == "")
    {
        QComboBox* cmb_ = (QComboBox*) this->findChild<QComboBox*>("ComboType" + QString::number(sender()->objectName().toInt()));
        cmb_->clear();
        //QMessageBox::about(0, sender()->objectName(), sender()->objectName());
        DeleteLimitLine(sender()->objectName().toInt()+1);
        return;
    }



    QComboBox* cmb = (QComboBox*) this->findChild<QComboBox*>("ComboType" + sender()->objectName());

    if (cmb==NULL)
        return;

    cmb->clear();
    cmb->addItem("Равно");
    cmb->addItem("Не равно");
    cmb->addItem("Больше");
    cmb->addItem("Меньше");


    QSqlRecord rec = p_SqlModel->record(1);

    if (rec.field(ColumnName).type() == QVariant::DateTime)
        cmb->addItem("Между");
    else if (rec.field(ColumnName).type() == QVariant::String)
    {
        cmb->addItem("Содержит");
        cmb->addItem("Не содержит");
    }
}

Здесь при выборе пустого элемента для фильтрации должна удаляться следующая строка фильтра - функция DeleteLimitLine, в которую передается номер текущей строки фильтра + 1

Сама функция вот
Код:
void Limit::DeleteLimitLine(int iIndex)
{
    QLayoutItem* f = p_GridLayout->itemAtPosition(iIndex, 0);


    int iCount = f->layout()->count();
    for (int i = 0; i < iCount; i++)
    {

        QWidget* p_wgt = f->layout()->itemAt(0)->widget();
        f->layout()->removeWidget(p_wgt);
        p_wgt->close();
        delete p_wgt;
    }


    p_GridLayout->removeItem(f);
    delete f;

    p_GridLayout->setSizeConstraint(QLayout::SetMinimumSize);
    this->resize(p_GridLayout->sizeHint().width(), p_GridLayout->sizeHint().height());


    iCountLimitLines--;
}
Т.е. получаем QLayoutItem - Layout строки фильтра по индексу.
Смотрим количество виджетов в этом Layout и удаляем каждый
Далее удаляем сам Layout.

Удаление проходит нормально. Только проблема в том что после удаления не перестраивается размер диалога. Точнее он перестраивается, но криво. Такое ощущение что в нем есть еще одна как бы невидимая строка - размер как раз подходит. Но строки нет.
Но.
Если до строки
Код:
p_GridLayout->setSizeConstraint(QLayout::SetMinimumSize);
Выводить сообщение (любое) QMessageBox
То диалог нормально перестраивается.
Причем это поэтапно выглядит так
1. Удаляются виджеты и Layout
2. Размер формы перестраивается как будто с еще одной строкой, которой нет
3. Показывается сообщение
4. Размер формы перестраивается идеально

Подскажите пожалуйста, почему такое может быть?

Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.044 секунд. Запросов: 22.