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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QTreeView проблемы с отрисовкой "GridLines"  (Прочитано 10307 раз)
neversleep
Гость
« : Август 09, 2011, 08:35 »

Создаю наследника от QTreeView, задаю модель с двумя колонками, и пытаюсь нарисовать разделительные линии между полями, а также вертикальную линию между колонками.

Cтолкнулся с такой проблемой, скриншот: http://savepic.net/1825769.png

Т.е получается какая-то смазанность линий... Это происходит при изменении размеров колонок, и перемотки по горизонтали (scroll).

И ещё иногда возникает такой глюк: http://savepic.net/1815529.png

Код:
class MyTreeView : public QTreeView
{
public:
    MyTreeView(QWidget *parent = 0) :
        QTreeView(parent)
    {
    }

protected:
    void paintEvent(QPaintEvent *event)
    {
        QTreeView::paintEvent(event);

        QPainter painter;
        painter.begin(viewport());
        painter.save();

        QPen pen(Qt::lightGray);
        pen.setStyle(Qt::DotLine);
        pen.setWidth(2);
        painter.setPen(pen);


        // рисуем вертикальную линию между столбцами
        QLine line(columnWidth(0), 0, columnWidth(0), height());

        painter.drawLine(line);

        painter.restore();
        painter.end();
    }

    void drawRow(QPainter *painter,
                 const QStyleOptionViewItem &options,
                 const QModelIndex &index) const
    {
        QTreeView::drawRow(painter, options, index);

        painter->save();

        QPen pen(Qt::lightGray);
        pen.setStyle(Qt::DotLine);
        pen.setWidth(2);
        painter->setPen(pen);


        // горизонтальная линия между полями
        QLine line(options.rect.left(), options.rect.bottom(),
                   options.rect.right(), options.rect.bottom());

        painter->drawLine(line);

        painter->restore();
    }
};

Помогите разобраться.

ps
Сначала пробовал рисовать из делегата, возникла эта же проблема..
Записан
AnubiSAD
Гость
« Ответ #1 : Август 09, 2011, 09:21 »

Возможно paintEvent каждый раз тебе перерисовывает линии не удаляя старые. У меня так было как-то. Рисуй линии не в PaintEvent, я делал это в конструкторе.
Записан
neversleep
Гость
« Ответ #2 : Август 09, 2011, 09:28 »

Рисуй линии не в PaintEvent, я делал это в конструкторе.
Вот с этого места по подробней если можно.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Август 09, 2011, 11:00 »

2 neversleep:
вот так взял и грубо дал ниже пояса троллям) И ещё удивляется откуда глюки)
Для таких вещей нужно задействовать делегаты:
Код
C++ (Qt)
void QStyledItemDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const [virtual]
Записан

Qt 5.11/4.8.7 (X11/Win)
AnubiSAD
Гость
« Ответ #4 : Август 09, 2011, 11:05 »

Да, согласен, не рисовал, конечно, извиняюсь. У меня немного другая ситуация была.
Записан
neversleep
Гость
« Ответ #5 : Август 09, 2011, 11:29 »

2 neversleep:
вот так взял и грубо дал ниже пояса троллям) И ещё удивляется откуда глюки)
Для таких вещей нужно задействовать делегаты:
Код
C++ (Qt)
void QStyledItemDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const [virtual]
Я только начал осваевать Qt Улыбающийся

Делаю:
Код:
void MyDelegate::paint(QPainter *painter,
  const QStyleOptionViewItem &option,
  const QModelIndex &index) const
{
    QStyledItemDelegate::paint(painter, option, index);

    painter->save();

    QPen pen(Qt::lightGray);
    pen.setStyle(Qt::DotLine);
    pen.setWidth(2);
    painter->setPen(pen);

    QRect rc(option.rect);
    if (index.column() == 0)
        rc.setLeft(0);

    QLine lines[2] = {
        QLine(rc.left(), rc.bottom(), rc.right(), rc.bottom()), // горизонтальная линия снизу
        QLine(rc.right(), rc.top(), rc.right(), rc.bottom())    // верт. линия справа
    };
    painter->drawLines(&lines[0], index.column() == 0 ? 2 : 1);
    painter->restore();
}

Глюк со смазыванием справа снимается, и этот вопрос тоже:
Цитировать
И ещё иногда возникает такой глюк: http://savepic.net/1815529.png

Но с левой стороны все по-прежнему, а если убрать:
Код:
    QRect rc(option.rect);
    if (index.column() == 0)
        rc.setLeft(0);
То всё нормально, только лини рисуются не "от начала" (с лева остаётся пустошь) Улыбающийся
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #6 : Август 09, 2011, 11:45 »

Цитировать
То всё нормально, только лини рисуются не "от начала" (с лева остаётся пустошь)
Ну и рисуй тогда для первой колонки от 0.
Записан

Qt 5.11/4.8.7 (X11/Win)
neversleep
Гость
« Ответ #7 : Август 09, 2011, 11:59 »

Цитировать
То всё нормально, только лини рисуются не "от начала" (с лева остаётся пустошь)
Ну и рисуй тогда для первой колонки от 0.
Заменить "if (index.column() == 0) rc.setLeft(0);" на "if (index.column() == 1) rc.setLeft(0);" Ты это имел ввиду ?  Строит глазки
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #8 : Август 09, 2011, 12:03 »

Да нет не это. Посмотрел внимательно код - ты так и делал.
Покажи скриншот.
Записан

Qt 5.11/4.8.7 (X11/Win)
neversleep
Гость
« Ответ #9 : Август 09, 2011, 12:18 »

С глюком: http://savepic.net/1821693.png
Без глюка: http://savepic.net/1824765.png // если убрать ...rc.setLeft(0);
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #10 : Август 09, 2011, 12:29 »

Цитировать
если убрать ...rc.setLeft(0);
А зачем убирать?
Записан

Qt 5.11/4.8.7 (X11/Win)
neversleep
Гость
« Ответ #11 : Август 09, 2011, 12:35 »

Да в том то и дело что не зачем, мне как раз так и надо чтобы линия рисовалась от самого края, с нуля, но тогда происходит размазывание линии если прокручивать по горизонтали, т.е если ширина колонок больше чем ширина дерева. А когда убираю setLeft(0), то смазывания не происходит, и всё в порядке.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #12 : Август 09, 2011, 13:03 »

С не SolidLine всегда сплошные проблемы. Кстати у троллей в QTableView тоже.
Забей и рисуй сплошной линией.
Записан

Qt 5.11/4.8.7 (X11/Win)
neversleep
Гость
« Ответ #13 : Август 09, 2011, 14:33 »

Вариант с сплошной линией я тоже рассматривал, как черновой...

Я нашёл решение, нужно устанавливать rc.left относительно позиции горизонтальной полосы прокрутки, т.е rc.setLeft(-horizontalScrollBarPos); Вот только tree->horizontalScrollBar().pos() всегда почему то возвращает QPoint(0,0), т.е нужно самому соединяться с сигналом valueChanged(int) скроллбара и запоминать позицию.

В итоге получилось:
Код:
    ...
    MyTreeView *tree = dynamic_cast<MyTreeView*>(parent());

    QRect rc(option.rect);
    if (index.column() == 0)
        rc.setLeft(-tree->m_hScrollPos);

    ...

Всем спасибо за помощь, вопрос решён.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #14 : Август 09, 2011, 14:49 »

Так по-проще будет:
Код
C++ (Qt)
MyTreeView *tree = dynamic_cast<MyTreeView*>(parent());
 
   QRect rc(option.rect);
   if (index.column() == 0)
       rc.setLeft(-tree->horizontalScrollBar()->value());
Записан

Qt 5.11/4.8.7 (X11/Win)
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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