Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как в ячейке таблице отображать виджет ?
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Модель/Представление
flankerr
Есть таблица. Надо в ячках вместо стандартной текстовой строки отображать виджет.
На сколько я понимаю тут нужен QItemDelegate. Как подсунуть виджет при редактировании примеров полно. Как отрисовать ячейку с нуля тоже понятно.
А вот как в ячейку в режиме отображения (не редактирования) подсунуть виджет ? И главное чтобы с этим виджетом можно было работать, ну всмысле он был не просто тупо картинкой а полностью рабочим, т.е реагировал на действия пользователя ??
SABROG
void QAbstractItemView::openPersistentEditor ( const QModelIndex & index )
rnd
Может быть еще QAbstractItemView::setIndexWidget
Vass
Вот это я вызываю в конструкторе класса наследуемого от QTreeView в своем проекте
setItemDelegateForColumn(progressColumn, new ProgressBarDelegate);


Вот так выглядит заголовок делегата
#include <QtGui/QItemDelegate>
#include <QProgressBar>

class ProgressBarDelegate : public QItemDelegate
{
    Q_OBJECT


public:
    ProgressBarDelegate(QWidget *parent = 0, Qt::Alignment alignment = Qt::AlignCenter) : QItemDelegate(parent), align(alignment) {}

    void paint(QPainter *painter, const QStyleOptionViewItem &option,
               const QModelIndex &index) const;
    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;

private:
    Qt::Alignment align;
};



Вот так выглядит его реализация:

#include "progressbardelegate.h"

void ProgressBarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                                const QModelIndex &index) const
{
    int progress = index.data(Qt::DisplayRole).toInt();

    QStyleOptionProgressBar progressBarOption;
    progressBarOption.rect = option.rect;
    progressBarOption.minimum = 0;
    progressBarOption.maximum = 100;
    progressBarOption.progress = progress;
    if (progress == -1)
    {
        progressBarOption.text = tr("Waiting.");
    }
    else if (progress == -2)
    {
        progressBarOption.text = tr("Pausing.");
    }
    else
    {
        progressBarOption.text = QString::number(progress) + "%";
    }
    progressBarOption.textVisible = true;
    progressBarOption.textAlignment = Qt::AlignHCenter;

    QApplication::style()->drawControl(QStyle::CE_ProgressBar,
                                       &progressBarOption, painter);
}

QWidget *ProgressBarDelegate::createEditor(QWidget *parent,
                                           const QStyleOptionViewItem &/*option */,
                                           const QModelIndex &/*index */) const

{
    QProgressBar *progressBar = new QProgressBar(parent);
    return progressBar;
}

void ProgressBarDelegate::setEditorData(QWidget *editor,
                                        const QModelIndex &index) const
{
    int value = index.data(Qt::DisplayRole).toInt();
    QProgressBar *progressBar = qobject_cast<QProgressBar *>(editor);
    if (value == -1)
    {
        progressBar->setFormat(tr("Waiting."));
        progressBar->setValue(0);
    }
    else if (value == -2)
    {
        progressBar->setFormat(tr("Pausing."));
        progressBar->setValue(0);
    }
    else
    {
        progressBar->setFormat("%p%");
        progressBar->setValue(value);
    }
}

void ProgressBarDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                       const QModelIndex &index) const
{
    QProgressBar *progressBar = qobject_cast<QProgressBar *>(editor);
    QString str = QString::number(progressBar->value());
    model->setData(index, str+"%", Qt::DisplayRole);
}


Вот так оно вызывается из модели (в переопределенной виртуальной ф-ции)
QVariant MyTableModel::data(const QModelIndex &index, int role) const


case progressColumn:
                if (command->state() == CommandInformation::New)
                {
                    return QString("-1");
                }
                else if (command->state() == CommandInformation::Pausing)
                {
                    return QString("-2");
                }
                else
                {
                    return QString::number(command->progress());
                }
                break;


Результатом является вполне функциональный прогрессбар в ячейке (у меня он отображает процент загрузки файла в дайнлоад менеджере)
SABROG
Цитата(Vass @ 19.10.2009, 17:30) *
QWidget *ProgressBarDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option */, const QModelIndex &/*index */) const { QProgressBar *progressBar = new QProgressBar(parent); return progressBar; }
Цитата(Vass @ 19.10.2009, 17:30) *
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter);


Похоже на масло маслянное. Когда ячейка не редактируется, то paintEvent рисует progressBar, кода редактируется (чтО можно редактировать в ячейке, задача которой всего-лишь отображать прогресс?), то поверх нарисованного прогресса создается уже настоящий QProgressBar. Т.е. по сути, в момент редактирования ячейки их 2 должно получиться.
Litkevich Yuriy
Цитата(SABROG @ 19.10.2009, 21:52) *
Т.е. по сути, в момент редактирования ячейки их 2 должно получиться.
в каждый момент один. По моему так
SABROG
Цитата(Litkevich Yuriy @ 19.10.2009, 21:13) *
Цитата(SABROG @ 19.10.2009, 21:52) *
Т.е. по сути, в момент редактирования ячейки их 2 должно получиться.
в каждый момент один. По моему так


Думаю ты прав. Но двойная работу все же присутствует. Остается только понять насколько сильно будет грузить приложение таблица с сотней открытых editoro'в.
Litkevich Yuriy
Цитата(SABROG @ 20.10.2009, 1:06) *
Остается только понять насколько сильно будет грузить приложение таблица с сотней открытых editoro'в.
можно посмотреть на моём примерчике (когда-то выкладывал). Вот его поправленный вариант. Нажмите для просмотра прикрепленного файла
собственно собирайте make debug и в консоли увидите какие методы делегата вызываются.

Делегаты проверяйте в первых двух строчках.

Обратите внимание на вторую строку первого столбца (с редактором даты) во время редактирования. Когда курсор мигает, всё время перерисовывается (вроде логично, но я не ожидал :lol: )
Vass
SABROG, Да, признаюсь перестарался :)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.