[Solved] How to display subscript text in header of QTableview.



  • Hi,

    I retrieve data from database and display those in QTableview. I'm using following method to set my header.

    @QVariant ComponentCollection::headerData ( int section ) const
    {
    switch (section)
    {
    case 0: return tr("Manufacturer");
    case 1: return tr("Rating");
    case 2: return tr("Mounting");
    case 3: return tr("I<sub>CW</sub>[KA/1S]");
    }
    }@

    But it is not execute the Html. Display 'I<sub>CW</sub>[KA/1S]' as text.

    Can anybody help me with displaying sub scripted text in header?

    Thanks in advance.


  • Moderators

    this is not supported by Qt, you would need to implement a QStyledItemDelegate and set it to your QHeaderView. (There are alot of examples on the web how to do this).
    In the paint() and sizeHint() use a QTextDocument:
    QTextDocument::drawContents() and QTextDocument::size()

    Note: Qt only supports a "HTML-subset":http://qt-project.org/doc/qt-4.8/richtext-html-subset.html.



  • I have the same problem. Delegates won't work, since the header of QTableView don't rely on delegates.

    Qt doc:
    Note: Each header renders the data for each section itself, and does not rely on a delegate

    At the moment, I think the only way is to override QHeaderView::paintSection method. But I don't know how. An example would be very nice! Or any other helpful suggestions (:

    Thanks in advance and best regards!


  • Moderators

    [quote author="CBurn" date="1376395150"]I have the same problem. Delegates won't work, since the header of QTableView don't rely on delegates.
    [/quote]
    Indeed. Thanks for pointing that out!

    Ok ... the solution is analog to the item delegates approach:
    @
    void MyHeaderView::paintSection(QPainter * painter, const QRect & rect, int logicalIndex) const
    {
    if (!rect.isValid())
    return;

    QStyleOptionHeader opt;
    initStyleOption(&opt);
    //....
    
    opt.text = "";   //IMPORTANT!
    
    // draw the section
    style()->drawControl(QStyle::CE_Header, &opt, painter, this);
    
    //now the paint the html text yourself 
    painter->save();
    
         QRect textRect = style()->subElementRect(QStyle::SE_HeaderLabel, &opt, this);
    
         m_TextDoc.setHtml(...);   //m_TextDoc is of type QTextDocument
         m_TextDoc.drawContents(painter, textRect);
    
    painter->restore();
    

    }
    @

    Note: i've only posted the relevant changes. Please take the rest from QHeaderView::paintSection() impleemntation source code.



  • Thank you very much for the quick answer!

    It works very well, but only for the first coloumn, although the text from the other columns is present in tmp.
    Also, the text won't be aligned in the middle of the column. Do you have any suggestions?

    This is what my paintSection() looks like:

    @void MyHeader::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
    {
    if (!rect.isValid())
    return;

    QStyleOptionHeader opt;
    initStyleOption(&opt);
    
    opt.rect = rect;
    opt.section = logicalIndex;
    opt.text = this->model()->headerData(logicalIndex, this->orientation(), Qt::DisplayRole).toString();
    opt.textAlignment = Qt::AlignCenter;
    
    // the section position
    
    int visual = visualIndex(logicalIndex);
    
    Q_ASSERT(visual != -1);
    
    if (count() == 1)
        opt.position = QStyleOptionHeader::OnlyOneSection;
    
    else if (visual == 0)
        opt.position = QStyleOptionHeader::Beginning;
    
    else if (visual == count() - 1)
        opt.position = QStyleOptionHeader::End;
    
    else
        opt.position = QStyleOptionHeader::Middle;
    
    QTextDocument TextDoc;
    QString tmp = opt.text;
    opt.text = "";   //IMPORTANT!
    
    // draw the section
    style()->drawControl(QStyle::CE_Header, &opt, painter, this);
    
    painter->save();
    
    QRect textRect = style()->subElementRect(QStyle::SE_HeaderLabel, &opt, this);
    TextDoc.setHtml(tmp);
    TextDoc.drawContents(painter, textRect);
    
    painter->restore();
    

    }@



  • Thank you very much for both of you..

    I create my own paintsection() using the reply of raven-worx.

    My paintSection() look like below. Hope CBurn can found answer for alignment issue.

    @void MyHeader::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
    {
    int header_column_num_need_to_change =10;

    painter->save();
    QHeaderView::paintSection(painter, rect, logicalIndex);
    painter->restore();
    
    
    if (logicalIndex == header_column_num_need_to_change)
    {
        const QString column_header_text=   (model()->headerData(logicalIndex,Qt::Horizontal,Qt::DecorationRole).toString());
        QStaticText column_header_static_text(( const QString) column_header_text );
    
        QPoint display_location((rect.width()- column_header_text.length())/3,rect.height()/4);
    
        painter-> drawStaticText(rect.left()+display_location.rx(),display_location.ry(),column_header_static_text);
    
    }
    

    }@

    Thanx again..

    Note: I used QStaticText here because it can execute html code.


  • Moderators

    yes you can also use QStaticText ... whatever is more convenient to you.

    QStaticText has methods for setting the text-width and also alignment:
    QStaticText::setTextWidth() and QStaticText::setTextOption()

    And so does QTextDocument: QTextDocument::setDefaultTextOption() and QTextDocument::setTextWidth()

    @CBurn:
    What do you mean it is only working for the first column? What happens with the others?



  • Thanks both of you for the reply!

    Only the first element is plotted by QTextDocument::drawContents(), although the QRect seems to be correct and the QTextDocument is not empty for the other columns.


  • Moderators

    maybe you need to add the following line (right before drawContents()):
    @
    painter->translate( opt.rect.topLeft() );
    @

    Otherwise can you please create a screenshot, i think i didn't get what the problem is exactly.



  • I tried your suggestions with the painter->translate(...). I doesn't have any effect.

    I made two screenshots.

    The first is the result with the paintSection-code above:
    !http://s3.imgimg.de/uploads/Capture114f95d8dJPG.jpg(Capture1)!

    The second is the outcome when I comment line 34 out
    @//opt.text = "";@

    !http://s3.imgimg.de/uploads/Capture2711fbc7eJPG.jpg(Capture2)!


  • Moderators

    ok checked your code. Use this section and it will work:
    @
    painter->save();

    QRect textRect = style()->subElementRect(QStyle::SE_HeaderLabel, &opt, this);
    
    painter->translate( textRect.topLeft() );
    
    TextDoc.setDocumentMargin(0);
    TextDoc.setHtml(tmp);
    TextDoc.drawContents(painter, QRect( QPoint(0,0), textRect.size()) );
    
    painter->restore();
    

    @



  • Perfect! All works fine now, the alignment, too.

    Thank you very much for your help!!!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.