PDA

View Full Version : Reimplemented QHeaderView paints wrong on scrolling



coyoteazul
31st May 2016, 17:15
Hi. I've reimplemented QHeaderView to rotate text on the vertical header of my table (a QStandardItem through a QSortProxyModel)
Whenever i scroll to the sides, the painting goes wrong. Like it couldn't paint the new column headers. Also if i do something to fire the paint event, it only paints right if i'm on the initial position. How can i get it to paint properly?
Thanks in advance for your help.


Initial position
http://image.prntscr.com/image/2893c3e7470f4a2485c3fc8c692c66ad.png

Scroll to the furthest right
http://image.prntscr.com/image/94f4138006b94d709359ed8001fa3ffe.png

Scroll back to initial position
http://image.prntscr.com/image/0c7727efa0df447a8a75b53f50ab270e.png


This is my reimplementation

#include <QObject>
#include <QHeaderView>
#include <QPainter>

class QHeaderViewR : public QHeaderView
{
QStringList heads;

public:
QHeaderViewR(QStringList _heads):QHeaderView(Qt::Horizontal)
{
heads = _heads;
this->setSectionResizeMode(QHeaderView::Fixed);
this->setSectionsClickable(true);
}

void paintSection(QPainter * painter, const QRect & rect, int logicalIndex) const
{
QPen pen(Qt::black);
painter->setPen(pen);

painter->rotate(90);
painter->translate(0,-rect.width()+1);

QRect copy = rect;

copy.setWidth(rect.height());
copy.setHeight(rect.width());
copy.moveTo(0,-this->sectionPosition(logicalIndex));

if (logicalIndex == 0) //Show a line on the left
{
copy.setHeight(rect.width()-1);
painter->drawText(copy,Qt::AlignCenter, heads.at(logicalIndex));
}
else
{
painter->drawText(copy,Qt::AlignCenter ,heads.at(logicalIndex));
}

painter->drawRect(copy);
}
signals:
void sectionPressed(int logicalIndex());
};

wysota
31st May 2016, 19:25
What happens if in paintSection you comment out all of your code and call the superclass implementation of the method? Do the problems with repainting go away?

coyoteazul
31st May 2016, 19:44
I didn't know you could do that. Yes, if i do that the repainting is done correctly, but the text is not rotated anymore


void paintSection(QPainter * painter, const QRect & rect, int logicalIndex) const
{
QHeaderView::paintSection(painter,rect,logicalInde x);
//old code commented out
}

wysota
31st May 2016, 20:48
This works for me just fine:


#include <QtWidgets>

class MyHeader : public QHeaderView {
public:
MyHeader(QWidget*parent = 0) : QHeaderView(Qt::Horizontal, parent) {

}
protected:
QSize sectionSizeFromContents(int logicalIndex) const {
QSize s = QHeaderView::sectionSizeFromContents(logicalIndex) ;
return QSize(s.height(), std::max(100, s.width()));
}

void paintSection(QPainter *painter, const QRect & rect, int logicalIndex) const {
if (logicalIndex % 2) {
painter->save();
painter->translate(rect.left(), rect.bottom());
painter->rotate(-90);
QRect r(0, 0, rect.height(), rect.width());
painter->setBrush(Qt::red);
painter->drawRect(r);
painter->drawText(r, Qt::AlignCenter, QString::number(logicalIndex+1));
painter->restore();
} else QHeaderView::paintSection(painter, rect, logicalIndex);
}
};

int main(int argc, char**argv) {
QApplication app(argc, argv);
QTableView view;
QStandardItemModel model(800,400);
view.setModel(&model);
view.setHorizontalHeader(new MyHeader);
view.show();
return app.exec();
}

anda_skoa
31st May 2016, 22:03
Right, I would have also recommended saving and restoring the painter

Cheers,
_

coyoteazul
31st May 2016, 22:15
It worked!. I tried using save and restoring when i first reimplemented this class, but it wouldn't work as expected for some reason (dumb me probably)
Thanks a lot!