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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Свой делегат в виде QTableView  (Прочитано 6419 раз)
Kunashir
Гость
« : Март 05, 2011, 15:34 »

День добрый!
Программа тянет данные из БД, для отображение использую QSqlRelationalTableModel и свой класс наследник от QTableView. Для отображение данных по внешним ключам решил сделать делегат, который будет показывать QTableView связной таблицы (алгоритм отображении связной таблице точно такой же).
Создаю делегат:

Код:
class DelegatPerson : public QItemDelegate
{
    Q_OBJECT
public:
    DelegatPerson (int id, QObject *parent = 0);
    QWidget *createEditor(QWidget *parent,
                          const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setEditorData (QWidget *editor, const QModelIndex &index) const;
    void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
    void updateEditorGeometry (QWidget *editor,
                              const QStyleOptionViewItem &option, const QModelIndex &index) const;
    virtual void paint (QPainter *painter,
                const QStyleOptionViewItem& option, const QModelIndex& index ) const;
private:
    CCatalogPerson catPerson; //это класс таблицы БД, данные которой и надо отображать
};

теперь в классе отображения первой таблицы делают так:

Код:
ViewUser::ViewUser (QWidget *parent)
    :  QTableView (parent)
{
    DelegatPerson *delPerson = new DelegatPerson (0, this);
    setItemDelegateForColumn(3, delPerson);
}

Если убрать 
Код:
DelegatPerson *delPerson = new DelegatPerson (0, this); 
то данные отображаются нормально иначе все ячейки пустое, но при этом делегат свои данные выдает.

Реализация делегата:

Код:
DelegatPerson::DelegatPerson (int id, QObject *parent)
    : QItemDelegate (parent)
{
    //TODO: в дальнейшем нужно реализовать чтобы
    //в форме справочника текущим был элемент с id

}

QWidget *DelegatPerson::createEditor(QWidget *parent,
                                     const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    //Редактором по идее должна быть форма списка справочника т.е. класс ViewPerson
    ViewPerson *editor = new ViewPerson (parent);
    //здесь уже остальные действия...
    editor->setModel(catPerson.getModel());
    editor->installEventFilter(const_cast<DelegatPerson*> (this));
    return editor;
}

void DelegatPerson::setEditorData(QWidget *editor, const QModelIndex &index) const
{

}

void DelegatPerson::setModelData(QWidget *editor,
                                 QAbstractItemModel *model, const QModelIndex &index) const
{

}

void DelegatPerson::updateEditorGeometry(QWidget *editor,
                                         const QStyleOptionViewItem &option, const QModelIndex &index) const
{

}

void DelegatPerson::paint (
            QPainter *painter,
            const QStyleOptionViewItem& option,
            const QModelIndex& index ) const {

    QString text;
    QRect rect;
    QVariant value;
    QStyleOptionViewItemV2 opt = setOptions(index, option);

    value = index.data(Qt::DisplayRole);
    text = QLocale().toString(value.toDouble(), 'f', 2);
    opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
    drawDisplay(painter, opt, opt.rect, text);

    //QPen pen = QPen(Qt::red, 2, Qt::DashLine,
    //                Qt::FlatCap, Qt::MiterJoin);
    //painter->setPen(pen);
    //painter->drawLine(opt.rect.left(), opt.rect.bottom(),
    //                  opt.rect.right(), opt.rect.bottom());
    //painter->drawLine(opt.rect.right(), opt.rect.top(),
    //                  opt.rect.right(), opt.rect.bottom());
}


Думаю может из-за этого что не сделал реализацию setEditorData, setModelData и updateEditorGeometry.
Но если в конструкторе не устанавливать  setItemDelegateForColumn(3, delPerson);, а даже просто оставить создание делегата - данные уже не отображаются.

Собственно вопрос - почему только инициализация экземпляра класса DelegatPerson в конструкторе ViewUser приводит к тому что данные не отображаются, хотя количество строк создается верное.
« Последнее редактирование: Март 07, 2011, 14:48 от Kunashir » Записан
Kunashir
Гость
« Ответ #1 : Март 09, 2011, 11:08 »

Оказывается дело было в этом:

Код:
m_dbase = new CDatabase ("user");


замена на:

Код:
m_dbase = new CDatabase ("user2");

Решило проблему, хотя не ясно все же в чем трабола была, может есть служебное подключение с именем "user" - в причинах пока не разобрался.
Записан
Kunashir
Гость
« Ответ #2 : Март 09, 2011, 17:28 »

Теперь вот возник новый вопрос:
для делегата я использую по сути другой QTableView, ну сделал методы который способны вернуть данные из модели в вызываемом QTableView, а вот как установить данные в ячеки QTableView, который использует вызываемый делегат?
Если с простыми делегатами понятно:
Код:
someDel->setData(value);  

или что-то подобное, но здесь получается что делегат на прямую не связан с ячейкой, которая по сути представляет этот делегат, или я что-то не допонимаю?
Записан
Kunashir
Гость
« Ответ #3 : Март 10, 2011, 11:05 »

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

Может есть у кого пример, как заменить стандартный ComboBox, который обычно используется как делегат для ячеек, отображающих данные по внешним ключам, на что-то другое - ведь если данных в связной таблице много выбирать их в ComboBox неудобно. В идеале хорошо бы чтобы по клике по ячейки, которая по сути хранить внешний ключ, появлялась форма связной таблицы, в которой можно сделать выбор.
Записан
CL0NE
Гость
« Ответ #4 : Март 23, 2011, 03:34 »

наподобие http://www.prog.org.ru/topic_16381_0.html ?
Записан
Kunashir
Гость
« Ответ #5 : Март 24, 2011, 16:13 »

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


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