PDA

View Full Version : Horizontal scroll bar on QTreeView



LynneV
8th November 2010, 05:21
Hello - I hope someone can help, I am stuck. I have a QTreeView, it displays data using a delegate with only a Paint function (it is not editable data) in a QDialog window. I cannot seem to get a horizontal scroll bar. The horizontal scroll bar policy is AsNeeded. I have set the width on column 0 (there is only one column) to wider than the width of the widget, no luck (after setting the model). I have set the size hint for the row in the model to wider than the width of the widget, no luck. I have set the SizeHint for the option/index in the delegate to wider than the width of the widget, no luck. I have set the paint rectangle to wider than the widget width - still no horizontal scroll bar. It truncates the text display (which is wider than the widget width). No one seems to have trouble getting a horizontal scroll bar... but I sure am! I get a vertical scroll bar without any problem.

wysota
8th November 2010, 09:27
May we see some code?

LynneV
8th November 2010, 15:23
Here is some code, I've cut and pasted so if I left out something interesting, please let me know. Thanks in advance for your kind assistance.

This is adding data rows to the model:

{
QStandardItem* row = new QStandardItem();
int the_level = outline->GetLevel();

XiObjectListIter<XiRwOutputColumn> iter( outline->GetColumnIter() );
for (iter.Head(); iter.Valid(); iter.Next())
iter.Data()->SetColumnText( iter.Data()->Evaluate() );

QVariant rpt_item_data;
rpt_item_data.setValue<XiRwOutputLine>( outline);
row->setData( rpt_item_data, Qt::DisplayRole );
QSize size = row->sizeHint();
size.setWidth( 1500 );
row->setSizeHint( size );
row->setFlags( Qt::NoItemFlags );
while (the_level <= indentations.last() && indentations.last() != 0 && (!outline->IsPreviewHdr().isEmpty() || outline->IsPreviewFtr() ) && rptItems.count() > 0) {
rptItems.pop_back(); //line that is the current header
rptItems.pop_back(); //that line's parent
indentations.pop_back();
}

if ( !outline->IsPreviewHdr().isEmpty() )
{
//append the header line, and then set me as the new parent
rptItems.last()->appendRow( row );
row->setData( outline->IsPreviewHdr(), Qt::UserRole+1 );
indentations << the_level;
if (rptItems.last()->rowCount() > 0) { //parent->rowCount() > 0
rptItems << rptItems.last()->child(rptItems.last()->rowCount()-1); //parent = parent->child( parent->rowCount()-1 );
rptItems << rptItems.last();
}
}
else
rptItems.last()->appendRow( row );

//after append:
int rpt_cnt = rptItems.count();
int child_cnt = rptItems.last()->rowCount();
}

This is the size hint in the delegate:


if (qVariantCanConvert<XiRwOutputLine>(index.model()->data(index, Qt::DisplayRole )))
{
XiRwOutputLine outline = qVariantValue<XiRwOutputLine>(index.model()->data( index, Qt::EditRole ));

QSize row_height = QStyledItemDelegate::sizeHint(option, index);
row_height.setHeight( outline->GetFHeight() );
row_height.setWidth( 1500 );
return row_height;
}
else{
QSize row_height = QStyledItemDelegate::sizeHint(option, index);
row_height.setHeight( row_height.height() );
row_height.setWidth( 1500 );
return row_height;
}

This is the paint function:


QRect paint_rect = option.rect;
XiRwOutputLine outline = qVariantValue<XiRwOutputLine>(index.model()->data( index, Qt::EditRole ));
paint_rect.setWidth( outline->GetWidth() );
painter->fillRect(paint_rect, qVariantValue<QBrush>(index.model()->data( index, Qt::BackgroundRole )));

QTextDocument q_txt;
QPen orig_pen = painter->pen();
QFont orig_font = painter->font();
//set line font,
QFont qfont = outline->GetQFont();
QColor qcolor = outline->GetColor();
QRect r = option.rect;
//iterate through columns and create a print line for painting
XiObjectListIter<XiRwOutputColumn> iter( outline->GetColumnIter() );
for (iter.Head(); iter.Valid(); iter.Next())
{
painter->setFont( iter.Data()->GetColumnFont() );
if( iter.Data()->GetColumnColor().isValid() )
painter->setPen( iter.Data()->GetColumnColor() );
else
painter->setPen( qcolor );

r.setWidth( iter.Data()->GetWidth() );
QString col_text( (char*)iter.Data()->GetColumnText());
if( col_text.contains( "<!DOCTYPE html" ) )
{
q_txt.setHtml( col_text );
QAbstractTextDocumentLayout::PaintContext context;
q_txt.setPageSize( r.size());
painter->translate(r.x(),r.y());
q_txt.documentLayout()->draw(painter, context);
painter->restore();
}
else
{
switch (iter.Data()->GetJustification()) {
case XiRwOutputColumn::Right:
painter->drawText(r,Qt::AlignRight,col_text);
break;
case XiRwOutputColumn::Center:
painter->drawText(r,Qt::AlignCenter,col_text);
break;
case XiRwOutputColumn::Wrap:
painter->drawText(r,Qt::TextWordWrap,col_text);
break;
default:
painter->drawText(r,col_text);
}
}
r.setLeft( r.right()+3);
}
painter->setFont( orig_font );
painter->setPen( orig_pen ) ;
}

else
{
QStyledItemDelegate::paint(painter, option, index);
}
this is the code for setting the model in the rpt_view TreeView:


if (realized)
{
report->finished = FALSE;
rpt_view->setItemDelegate( new RWPreviewDelegate( ));
rpt_view->setModel( rpt_model );
rpt_view->setColumnWidth( 0,1500 );
if( report->finished )
report->UnRealize();
}

wysota
8th November 2010, 16:04
How is your view set up? Does it have stretchLastColumn property set to true? What are the resize policies of the columns?

LynneV
8th November 2010, 17:41
Thank you so much for your quick response - it is appreciated. I'm using the Qt designer for this dialog, and all the items are set to the default except that I turned off word wrap and set the horizontal scroll bar to 'Always On'. I see a stretchHeaderLastSection, and that's checked. But I don't have a header, do I need one? The size policy for the QTreeView is Preferred, Expanding. I don't see a stretchLastColumn property or resize policies for individual columns - I must be looking in the wrong place, where do I find those? I set the resizeColumnToContents(0), but it doesn't seem to make a difference. Thanks again for your help.

wysota
9th November 2010, 10:20
I see a stretchHeaderLastSection, and that's checked.
Switch it off.

But I don't have a header, do I need one?
With a tree view you always have a header, it might not be visible though.

I don't see a stretchLastColumn property or resize policies for individual columns - I must be looking in the wrong place, where do I find those?
In the docs of QHeaderView :)


I set the resizeColumnToContents(0)
Bad idea.

LynneV
9th November 2010, 20:19
The solution ended up to be: QStandardItemModel->SetHorizontalHeaderLabels( QStringList) AND QTreeView->setColumnWidth( 0, line_width ). Ether alone would not work..but together they do the trick! Why is resizeColumntoContents not a good idea? Just curious.

wysota
9th November 2010, 21:05
Why is resizeColumntoContents not a good idea?
Because you are probably calling it before the sizes are calculated so it's likely a no-op.