Шаг 103.
Библиотека Qt.
Делегат, как часть технологии "интервью"

    На этом шаге рассмотрим понятие "делегата", как части технологии "интервью".

    Для стандартных представлений списков и таблиц отображение элементов выполняется посредством делегирования. Это позволяет очень просто создавать представления для любых нужд без написания большого количества нового кода. Делегат отвечает за рисование каждого элемента и за его редактирование (изменение пользователем).

    В Qt есть готовый класс делегата QItemDelegate (рис. 1), который предоставляет методы редактирования каждой записи при помощи элемента однострочного текстового поля, и для большинства случаев его вполне достаточно.


Рис.1. Классы делегатов

    Но если вам потребуется осуществлять особый контроль над отображением и редактированием данных, то для этого понадобится создать свой собственный делегат. Для этого необходимо унаследовать свой класс либо от QAbstractItemDelegate, либо от QItemDelegate.

    Давайте реализуем простой пример делегата, который выделяет элемент, как только пользователь проведет над ним курсор (указатель) мыши (рис. 2).


Рис.2. Демонстрация делегата

    Рассмотрим класс, описанный в программе и предназначенный для реализации выделения элемента при наведении на него курсора мыши:

//унаследован от класса QItemDelegate
class SimpleDelegate : public QItemDelegate {
public:
    SimpleDelegate(QObject* pobj = 0) : QItemDelegate(pobj)
    {
  }
//В методе для рисования paint() мы получаем три аргумента.
//Первый аргумент — это указатель на объект класса QPainter.
//Второй — это ссылка на структуру QStyleOptionViewItem,
//определенную в классе QStyle. Третий — модельный индекс.
//Для перерисовки элемента каждый раз, когда пользователь проведет над ним мышь,
//мы просто проверяем флаги состояния установленных битов объекта структуры option,
//чтобы определить, находится ли мышь на элементе или нет. 
//Если биты флага QStyle::State_MouseOver установлены,
//это значит, что курсор мыши находится над элементом и,
//в этом случае, его фон рисуется при помощи линейного градиента
    void paint(QPainter* pPainter,
               const QStyleOptionViewItem& option,
               const QModelIndex& index
               ) const
    {
        if (option.state & QStyle::State_MouseOver)
        {
            QRect rect = option.rect;
            QLinearGradient gradient(0, 0, rect.width(), rect.height());
            gradient.setColorAt(0, Qt::red);
            gradient.setColorAt(0.25, Qt::yellow);
            gradient.setColorAt(0.5, Qt::green);
            gradient.setColorAt(0.75, Qt::cyan);
            gradient.setColorAt(1, Qt::blue);
            pPainter->setBrush(gradient);
            pPainter->drawRect(rect);
        }
        QItemDelegate::paint(pPainter, option, index);
    }
};

    В функции main() вызов метода setItemDelegate() устанавливает в представлении объект созданного нами делегата (класс SimpleDelegate).

    Для того чтобы представление реагировало на перемещения курсора мыши над ним, необходимо установить в окне просмотра флаг Qt::WA_Hover при помощи метода setAttribute().

pListView->setItemDelegate(new SimpleDelegate(pListView));
pListView->viewport()->setAttribute(Qt::WA_Hover);

    Файлы приложения можно взять здесь.

    На следующем шаге рассмотрим классом QModelIndex.




Предыдущий шаг Содержание Следующий шаг