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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как обновить ячейку QModelIndex?  (Прочитано 4779 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Май 24, 2013, 17:48 »

Привет. Как можно заставить обновиться ячейку QTreeView зная QModelIndex из делегата?
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #1 : Май 24, 2013, 17:49 »

Есть узел дерева, в нем два подузла (допустим SpinBox), мне нужно при изменении значения одного из спинбоксов заставить обновить значение родительского узла.
Записан
mutineer
Гость
« Ответ #2 : Май 24, 2013, 17:52 »

Сделать setData в модель
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #3 : Май 27, 2013, 08:43 »

я так и понял, подругому никак?
Записан
Bepec
Гость
« Ответ #4 : Май 27, 2013, 09:14 »

Как вариант написать в моделе слотик, позволяющий обновлять любую ячейку посылом сигнала dataChanged.
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #5 : Май 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();
}

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

Сообщений: 2921



Просмотр профиля
« Ответ #6 : Май 27, 2013, 11:36 »

Код
C++ (Qt)
connect(comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(commitAndCloseEditor()));
У тебя же делается коммит при изменении индекса. Только вот зачем в этом случае ещё и закрывать его Непонимающий
Записан

Qt 5.11/4.8.7 (X11/Win)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #7 : Май 28, 2013, 09:42 »

Все делалось по примеру. close я убрал, но ничего не помогает. в setModelData заходит только после того, как editor теряет фокус Грустный
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #8 : Июнь 04, 2013, 11:02 »

есть еще идеи?
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #9 : Июнь 04, 2013, 11:28 »

разобрался, так как виджеты-редакторы находятся в виджете-контейнере, то в emit нужно слать указатель на контейнер, а не на виджет, который шлет сигнал изменения значения
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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