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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: При вызове метода closeEditor для наследника QTableView editor не удаляется.  (Прочитано 1953 раз)
smallmazila
Гость
« : Декабрь 29, 2011, 13:35 »

Приветствую всех участников форума!

Кратко о задаче:
Есть связка LVTableView, LVTableItemDelegate и CableComboBox. Каждый объект является наследником соответственно от QTableView, QItemDelegate, QComboBox.

LVTableView.cpp
Код:
#include "LVTableView.h"

#include "LVModel.h"

LVTableView::LVTableView(DataModel* model)
{
if (model)
setModel(model);
}

LVTableView::~LVTableView()
{

}

void LVTableView::init(DataModel* model)
{
clearSpans();
if (model)setModel(model);
LVModel* lvm = dynamic_cast<LVModel*>(this->model());
if (lvm && lvm->getRowCount() > 0)
{
setSpan(0,LVModel::NOMVOLTAGE_ID,lvm->getRowCount(),1);
setSpan(0,LVModel::WIRESPOSITION_ID,lvm->getRowCount(),1);
setSpan(0,LVModel::SOURCEVOLTAGE_ID,lvm->getRowCount(),1);
setSpan(0,LVModel::SUMLOSTVOLTAGE_ID,lvm->getRowCount(),1);
}
resizeRowsToContents();
resizeColumnsToContents();
}

void LVTableView::setModel(DataModel* model)
{
LVModel* m = dynamic_cast<LVModel*>(model);
if (m)
QTableView::setModel(m);
}

void LVTableView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint)
{
QTableView::closeEditor(editor,hint);
}

LVTableItemDelegate.cpp
Код:
#include "LVTableItemDelegate.h"

#include "Sector.h"
#include "BaseLineCalcControls.h"
#include "LVModel.h"
#include "LVModelEditController.h"
#include "LVEditors.h"

LVTableItemDelegate::LVTableItemDelegate(LVModelEditController*mec, QWidget *parent /* = 0 */)
: QItemDelegate(parent)
{
}

LVTableItemDelegate::~LVTableItemDelegate()
{
if (m_modelEditController)
delete m_modelEditController;
}

void LVTableItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QItemDelegate::paint(painter, option, index);
}

QWidget* LVTableItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.column() == LVModel::VISIBLE_ID)
return 0;
else if (index.column() == LVModel::NUMBER_ID)
{
QComboBox *combo = qobject_cast<QComboBox*>(LVEditors::LVSectorNameEditor(m_modelEditController->field(index), m_sectorNames, parent).editor());
return combo;
}
else if (index.column() == LVModel::SPECRESISTLEP_ID)
{
QComboBox *combo = qobject_cast<QComboBox*>(LVEditors::LVWireSpecResistEditor(m_activeResistNames,m_activeResistSections,parent).editor());
return combo;
}
        else
return QItemDelegate::createEditor(parent, option, index);
}

void LVTableItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if (index.column() == LVModel::NUMBER_ID)
{
QString text = index.model()->data(index).toString();
LVEditors::LVSectorNameEditor::setData(editor,QVariant(text));
}
else if (index.column() == LVModel::SPECRESISTLEP_ID)
{
QString text = index.model()->data(index).toString();
LVEditors::LVWireSpecResistEditor::setData(editor,QVariant(text));
}
else
QItemDelegate::setEditorData(editor,index);
}

void LVTableItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
if (index.column() == LVModel::NUMBER_ID)
{
QString text = LVEditors::LVSectorNameEditor::getData(editor).toString();
model->setData(index, text);
}
else if (index.column() == LVModel::SPECRESISTLEP_ID)
{
QString text = LVEditors::LVWireSpecResistEditor::getData(editor).toString();
QString sectionText = LVEditors::LVWireSpecResistEditor::getSectionData(editor).toString();
model->setData(index, text);
QModelIndex sectionIndex = model->index(index.row(),LVModel::CABLESECTION_ID);
model->setData(sectionIndex,sectionText);
}
else
QItemDelegate::setModelData(editor,model,index);
}

void LVTableItemDelegate::updateEditorGeometry ( QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
QItemDelegate::updateEditorGeometry(editor,option,index);
}

LVEditors.h
Код:
#ifndef LVEDITORS_H
#define LVEDITORS_H

#include "BaseEditor.h"

#include <QComboBox>
#include <QLineEdit>
#include <QFile>
#include <QTextStream>
#include <QCheckBox>
#include <QStringList>

#include "LVSector.h"
#include "BaseBreakNode.h"
#include "LVNode.h"

namespace LVEditors
{
/************************************************************************/
/* LVSectorNameEditor - редактор поля Номер участка                   */
/* Входные параметры:                     */
/* sector - участок ЛЭП */
/* parent - родительский Widget */
/* Выходные параметры: */
/* m_editor - Widget редакитрования Номера участка */
/* доступ через метод editor() */
/************************************************************************/
class LVSectorNameEditor
: public BaseEditor
{
public:
LVSectorNameEditor(Sector*sector, QStringList* sectorNames, QWidget*parent = 0)
: m_sector(sector), m_sectorNames(sectorNames), m_parent(parent)
{
m_editor = 0;
init();
}
virtual ~LVSectorNameEditor(){};
void init()
{
QComboBox *combo = new QComboBox(m_parent);
combo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
QLineEdit*lineEdit = new QLineEdit();
combo->setLineEdit(lineEdit);
LVSector* lvsector = dynamic_cast<LVSector*>(m_sector);
if (lvsector && lvsector->getPrevNode())
combo->addItem(lvsector->getName());
if (dynamic_cast<LVNode*>(lvsector->getNode()))
combo->addItem(lvsector->getName());
combo->addItem(BaseBreakNode::getBreakString());
if (m_sectorNames)
for (int i = 0; i < m_sectorNames->size(); i++)
combo->addItem(m_sectorNames->at(i));
m_editor = combo;
}
static QVariant getData(QWidget* widget)
{
QComboBox *comboBox = qobject_cast<QComboBox*>(widget);
return QVariant(comboBox?comboBox->currentText():"");
}
static void setData(QWidget* widget, QVariant val)
{
QComboBox *comboBox = qobject_cast<QComboBox*>(widget);
if (comboBox)
{
int comboIndex = comboBox->findText(val.toString());
comboBox->setCurrentIndex(comboIndex);
}
}
private:
QStringList* m_sectorNames;
Sector* m_sector;
QWidget*m_parent;
};

/************************************************************************/
/* CableComboBox     - Widget для редактирвоания поля Удельное   */
/* активное сопротивление ВЛ (Rо.вл) */
/* Входные параметры:                     */
/* parent - родительский Widget */
/* Поля: */
/* section - список доступных площадей сечений провода */
/************************************************************************/
class CableComboBox : public QComboBox
{
public:
CableComboBox(QWidget *parent = 0)
:QComboBox(parent)
{
};
~CableComboBox(){};

QStringList section;
};

/************************************************************************/
/* LVWireSpecResistEditor - редактор поля Удельное активное */
/*   сопротивление ВЛ (Rо.вл)         */
/* Входные параметры:                     */
/* parent - родительский Widget */
/* Выходные параметры: */
/* m_editor - Widget редакитрования Удельное активное */
/* сопротивление ВЛ (Rо.вл) */
/* доступ через метод editor() */
/************************************************************************/
class LVWireSpecResistEditor
: public BaseEditor
{
public:
LVWireSpecResistEditor(QStringList* activeResistNames, QStringList* activeResistSections, QWidget*parent = 0)
: m_parent(parent), m_activeResistNames(activeResistNames), m_activeResistSections(activeResistSections)
{
m_editor = 0;
init();
}
~LVWireSpecResistEditor(){};
void init()
{
CableComboBox *comboBox = new CableComboBox(m_parent);
comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
if (m_activeResistNames && m_activeResistSections)
for (int i = 0; i < m_activeResistNames->size(); i++)
{
comboBox->addItem(m_activeResistNames->at(i));
comboBox->section.append(m_activeResistSections->at(i));
}
m_editor = comboBox;
}
static QVariant getData(QWidget* widget)
{
QComboBox *comboBox = qobject_cast<QComboBox*>(widget);
return QVariant(comboBox?comboBox->currentText():"");
}
static void setData(QWidget* widget, QVariant val)
{
CableComboBox *comboBox = dynamic_cast<CableComboBox*>(widget);
if (comboBox)
{
int comboIndex = comboBox->findText(val.toString());
comboBox->setCurrentIndex(comboIndex);
}
}
static QVariant getSectionData(QWidget* widget)
{
CableComboBox *comboBox = dynamic_cast<CableComboBox*>(widget);
return QVariant((comboBox && comboBox->currentIndex() > -1)?comboBox->section.at(comboBox->currentIndex()):"");
}
private:
QStringList *m_activeResistSections;
QStringList *m_activeResistNames;
QWidget*m_parent;
};
};
#endif //LVEDITORS_H

Классу LVTableView назначается делегат LVTableItemView, в методе createEditor создаются два редактора для сответствующих слобцов таблицы:
LVWireSpecResistEditor
и
LVSectorNameEditor.

для первого используется наследник QComboBox - CableComboBox.

ПРОБЛЕМА: при потере фокуса Editor-а или нажатии Enter при активном Editor-е наблюдается два исхода:
1. отрабатывает как должно: из Editor-а данные переносятся в модель и редактор удалется.
2. отрабатывает не корректно: из Editor-а данные переносятся в модель, а редактор не удаляется, а остается активным. Причем ни обновление данных в модели, ни потеря фокуса Editor-ом ни нажатие Enter не приводят к удалению Editor-а.
Соотношение корректных и некорректных исходов где то 80 на 20.

Если кто сталкивался с такой проблемой подскажите как ее решить.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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