Проблема отрисовки рисованной линии в QTableWidgetItem

Я хотел бы нарисовать линию внутри QTableWidgetItem, Чтобы нарисовать линию, я переопределил QStyledItemDelegate::paint метод.

Но когда я прокручиваю или выбираю элемент в QTableWidget, Некоторые предметы теряют эффект рисования.

Вот моя реализация рисования:

void DrawLineDelegate::paint(QPainter *poPainter, const QStyleOptionViewItem &oOption, const QModelIndex &oIndex) const
{
    // Valid index ?
    if(!oIndex.isValid())
        // Not valid.
        return;

    const QRect oRect( oOption.rect );

    // Painter has certain settings
    poPainter->save();

    // Draw line
    QColor oLineColor (oIndex.data(Qt::UserRole).toString());

    poPainter->setRenderHint(QPainter::Antialiasing);
    poPainter->setPen(QPen(oLineColor, 2, Qt::SolidLine, Qt::RoundCap));
    poPainter->drawLine(oRect.left(),                       // Start X-coordinate
                        oRect.top() - oRect.height() / 2 ,  // Center Height (Y-coordinate)
                        oRect.left() + oRect.width(),       // Line width
                        oRect.top() - oRect.height() / 2);  // Center Height (Y-coordinate)

    poPainter->restore();

    QStyledItemDelegate::paint( poPainter, oOption, oIndex );
}

В функции инициализации TableWidget я установил элемент делегата следующим образом

ui->tableWidget->setItemDelegateForColumn(2, new DrawLineDelegate(this) );

Примечание: каждый элемент я сохраняю название цвета как Qt::UserData,

На столе инициализации линии хорошо рисуются, ошибка, когда я играю со столом.

Вот несколько скриншотов

Перед прокруткой

После прокрутки

После выбора строки

Какие-либо предложения?

1 ответ

ОК, мне удалось решить мою проблему благодаря подсказке Кубы Обер.

Исправления:

  1. Я пропустил вычисление высоты строки, чтобы она выходила за границы элемента таблицы. (поэтому я переключил "-" на "+" в функции DrawLine)
  2. Добавлена ​​обработка выделения выделения строк.
  3. Перед рисованием перемещена базовая функция рисования QStyledItemDelegate.

Вот полный рабочий ответ.

void DrawLineDelegate::paint(QPainter *poPainter, const QStyleOptionViewItem &oOption, const QModelIndex &oIndex) const
{
    QStyle *poStyle;
    bool bSelected;

    // Valid index ?
    if(!oIndex.isValid())
        // Not valid.
        return;

    QStyledItemDelegate::paint( poPainter, oOption, oIndex );

    if (oIndex.column() == COLUMN_COLOR_ID) {

        const QRect oRect( oOption.rect );
        QColor oLineColor (oIndex.data(Qt::UserRole).toString());

        QStyleOptionViewItemV4 oOptv4 = oOption;
        initStyleOption(&oOptv4, oIndex);

        const QWidget *poWidget = oOption.widget;

        // Style option
        poStyle =
                poWidget ? poWidget->style() : QApplication::style();

        // Set pen
        poPainter->setPen(QPen(oLineColor, 2, Qt::SolidLine, Qt::RoundCap));

        // Selection state
        bSelected =
                oOption.state&QStyle::State_Selected;

        // Item selected ?
        if (bSelected)
        {
            poPainter->setBrush(oOption.palette.highlightedText());
            // This call will take care to draw line while selecting
            poStyle->drawControl(QStyle::CE_ItemViewItem, &oOptv4, poPainter, poWidget);
        }

        // Draw line in the middle of the item
        poPainter->drawLine( oRect.left(),                          // Start X-coordinate
                             oRect.top() + oRect.height() / 2,      // Center Height (Y-coordinate)
                             oRect.left() + oRect.width(),          // Line width
                             oRect.top()  + oRect.height() / 2);    // Center Height (Y-coordinate)
    }


}   
Другие вопросы по тегам