Russian Qt Forum

Qt => Model-View (MV) => Тема начата: Fregloin от Май 24, 2013, 17:48



Название: Как обновить ячейку QModelIndex?
Отправлено: Fregloin от Май 24, 2013, 17:48
Привет. Как можно заставить обновиться ячейку QTreeView зная QModelIndex из делегата?


Название: Re: Как обновить ячейку QModelIndex?
Отправлено: Fregloin от Май 24, 2013, 17:49
Есть узел дерева, в нем два подузла (допустим SpinBox), мне нужно при изменении значения одного из спинбоксов заставить обновить значение родительского узла.


Название: Re: Как обновить ячейку QModelIndex?
Отправлено: mutineer от Май 24, 2013, 17:52
Сделать setData в модель


Название: Re: Как обновить ячейку QModelIndex?
Отправлено: Fregloin от Май 27, 2013, 08:43
я так и понял, подругому никак?


Название: Re: Как обновить ячейку QModelIndex?
Отправлено: Bepec от Май 27, 2013, 09:14
Как вариант написать в моделе слотик, позволяющий обновлять любую ячейку посылом сигнала dataChanged.


Название: Re: Как обновить ячейку QModelIndex?
Отправлено: Fregloin от Май 27, 2013, 11:04
Решил сделать через setData по умному.
Все хорошо, но есть одно НО: при выборе нового индекса в комбобоксе, данные в модель не заносятся, пока комбобокс не потеряет фокус.

Код:
QWidget *CObjectInspectorTreeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(option)
    if(index.isValid() && fmodel)
    {
        PropertyTreeNode    *   propertyNode = index.data(CObjectInspectorTreeModel::TreeNodeRole).value<PropertyTreeNode*>();
        if(!propertyNode || propertyNode==fmodel->rootNode() || index.column()==0)
            return NULL;

        QWidget *   editor = NULL;

        QVariant    indexValue = index.data(Qt::EditRole);
        if(!indexValue.isValid())
            return  NULL;

        if(!propertyNode->isExpandable())
        {
            if(propertyNode->metaProperty().isEnumType())
            {
                QComboBox   *   comboBox = new QComboBox;
                connect(comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(commitAndCloseEditor()));
                comboBox->setFrame(false);
                EnumProperty    *   enumProp = qobject_cast<EnumProperty*>(propertyNode);
                Q_ASSERT(enumProp);
                comboBox->addItems(enumProp->enumeratedProperties());
                editor = comboBox;
            }
            else
            switch (propertyNode->value().type())
            {
            case QVariant::Bool:
            {
                QCheckBox   *   checkBox = new QCheckBox;
                connect(checkBox,SIGNAL(clicked()),this,SLOT(commitAndCloseEditor()));
                editor = checkBox;
                break;
            }
            case QVariant::Int:
            case QVariant::LongLong:
            {
                QSpinBox    *   spinBox = new QSpinBox;
                spinBox->setFrame(false);
                spinBox->setMinimum(INT_MIN);
                spinBox->setMaximum(INT_MAX);
                connect(spinBox,SIGNAL(valueChanged(int)),this,SLOT(commitEditor()));
                editor = spinBox;
                break;
            }
....

Код:
void CObjectInspectorTreeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    if(index.isValid())
    {
        QPropertyEditWidget *   propertyEditor = qobject_cast<QPropertyEditWidget*>(editor);
        Q_ASSERT(propertyEditor);

        PropertyTreeNode    *   propertyNode = index.data(CObjectInspectorTreeModel::TreeNodeRole).value<PropertyTreeNode*>();
        Q_ASSERT(propertyNode);

        if(propertyNode->isExpandable())
            return;

        const   QMetaProperty   &   indexMetaProperty = propertyNode->metaProperty();
        if(indexMetaProperty.isFlagType())
        {
            QCheckBox   *   checkBox = qobject_cast<QCheckBox*>(propertyEditor->widget());
            Q_ASSERT(checkBox);
            model->setData(index,checkBox->isChecked());
            return;
        }

        if(indexMetaProperty.isEnumType())
        {
            QComboBox   *   comboBox = qobject_cast<QComboBox*>(propertyEditor->widget());
            Q_ASSERT(comboBox);
            model->setData(index,comboBox->currentIndex());
            return;
        }

        switch (indexMetaProperty.type())
        {
        case    QVariant::Bool:
        {
            QCheckBox   *   checkBox = qobject_cast<QCheckBox*>(propertyEditor->widget());
            Q_ASSERT(checkBox);
            model->setData(index,checkBox->isChecked());
        }
            break;
        case    QVariant::Int:
        case    QVariant::UInt:
        case    QVariant::LongLong:
        case    QVariant::ULongLong:
        {
            QSpinBox    *   spinBox = qobject_cast<QSpinBox*>(propertyEditor->widget());
            Q_ASSERT(spinBox);
            model->setData(index,spinBox->value());
        }
            break;
...

Код:
void CObjectInspectorTreeDelegate::commitAndCloseEditor()
{
    QWidget *   senderWidget = qobject_cast<QWidget*>(sender());
    Q_ASSERT(senderWidget);
    emit        commitData(senderWidget);
    emit        closeEditor(senderWidget,QAbstractItemDelegate::SubmitModelCache);
}

void CObjectInspectorTreeDelegate::commitEditor()
{
    QWidget *   senderWidget = qobject_cast<QWidget*>(sender());
    Q_ASSERT(senderWidget);
    emit        commitData(senderWidget);
    senderWidget->close();
}

Т.е. мне нужно что бы в реалтайме в модель заносились данные, а не по завершении/закрытии виджета-редактора.
По форуму рылся, решения не нашёл. Вроде получается и работает, но не так как хочется.


Название: Re: Как обновить ячейку QModelIndex?
Отправлено: GreatSnake от Май 27, 2013, 11:36
Код
C++ (Qt)
connect(comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(commitAndCloseEditor()));
У тебя же делается коммит при изменении индекса. Только вот зачем в этом случае ещё и закрывать его ???


Название: Re: Как обновить ячейку QModelIndex?
Отправлено: Fregloin от Май 28, 2013, 09:42
Все делалось по примеру. close я убрал, но ничего не помогает. в setModelData заходит только после того, как editor теряет фокус :(


Название: Re: Как обновить ячейку QModelIndex?
Отправлено: Fregloin от Июнь 04, 2013, 11:02
есть еще идеи?


Название: Re: Как обновить ячейку QModelIndex?
Отправлено: Fregloin от Июнь 04, 2013, 11:28
разобрался, так как виджеты-редакторы находятся в виджете-контейнере, то в emit нужно слать указатель на контейнер, а не на виджет, который шлет сигнал изменения значения