Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to set orientation of text in horizontal header ?
QtWS25 Last Chance

How to set orientation of text in horizontal header ?

Scheduled Pinned Locked Moved General and Desktop
18 Posts 3 Posters 19.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Anticross
    wrote on last edited by
    #1

    I've got QTableWidget with horizontal and vertical header. I need to change text orientation in vertical header items to save some place in table. Because the data in table items is just checkBox which can be checked or unchecked. So the question is: is it possible to change text orientation in horizontal header items and if it does, how can I change it ?

    1 Reply Last reply
    0
    • G Offline
      G Offline
      giesbert
      wrote on last edited by
      #2

      you can create a delegate to achieve this.
      A header is just a QHeaderView which is derived from QAbstractItemView. So you can create a delegate and set the delegate to the header view. The delegate could do text drawing in any rotation.

      Nokia Certified Qt Specialist.
      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

      1 Reply Last reply
      0
      • A Offline
        A Offline
        andre
        wrote on last edited by
        #3

        [quote author="Gerolf" date="1302249490"]you can create a delegate to achieve this.
        A header is just a QHeaderView which is derived from QAbstractItemView. So you can create a delegate and set the delegate to the header view. The delegate could do text drawing in any rotation.[/quote]

        Actually, delegates don't work for QHeaderView rendering. The documentation states:
        [quote]
        Note: Each header renders the data for each section itself, and does not rely on a delegate. As a result, calling a header's setItemDelegate() function will have no effect.[/quote]
        So, subclass QHeaderView and reimplement paintEvent().

        1 Reply Last reply
        0
        • G Offline
          G Offline
          giesbert
          wrote on last edited by
          #4

          Oh, sorry, havent seen this,

          But i suggest overwriting paintSection instead of paintEvent :-)

          Nokia Certified Qt Specialist.
          Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #5

            Yes, great plan :-)

            1 Reply Last reply
            0
            • A Offline
              A Offline
              Anticross
              wrote on last edited by
              #6

              I added a class based by QHeaderView but I can't change orientation of text. Where do I make mistake:
              @protected: void paintSection ( QPainter * painter, const QRect & rect, int logicalIndex ) const{
              if(m_orientation == Qt::Horizontal)
              {
              painter->save();
              QHeaderView::paintSection(painter, rect, logicalIndex);
              painter->restore();
              painter->rotate(90);
              }
              else
              QHeaderView::paintSection (painter,rect,logicalIndex );
              }@

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andre
                wrote on last edited by
                #7

                You first painting, and then rotating. That doesn't work. First rotate, and then paint. However, I think you will have to do the painting of the background yourself first (reference the implementation of QHeaderView for details on how to do that), then save the painter state, then rotate the painter, and then paint the text. Then, at the end of rotating, you restore the painter.

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  Anticross
                  wrote on last edited by
                  #8

                  I don't know what text I need to draw, because it's in UI or added by setHorizontalHeaderLabels(setVerticalHeaderLabels), so I need to rotate all containing data in header. How can I store all this data to paint after rotating painter ? And then draw. It also been useful when header item will resize to it's content.

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andre
                    wrote on last edited by
                    #9

                    Yes, you do know what text to draw, as you have access to the logicalIndex. Reference the implementation of QHeaderView for how drawing is implemented there. The paintSection method in that class -uses- should use the exact same data that you have available in your implementation of paintSection.

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      Anticross
                      wrote on last edited by
                      #10

                      In Assistant i find only this:
                      void QHeaderView::paintSection ( QPainter * painter, const QRect & rect, int logicalIndex ) const [virtual protected]

                      Paints the section specified by the given logicalIndex, using the given painter and rect.

                      Normally, you do not have to call this function.

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        andre
                        wrote on last edited by
                        #11

                        I mean: open up the source code of QHeaderView to take a peek on how this works in Qt, and use that solution as inspiration on how your own implementation may work. Since we're all developers here, I assume you're not afraid to read source code?

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          Anticross
                          wrote on last edited by
                          #12

                          Thanks, Andre, I will look at it.

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            Anticross
                            wrote on last edited by
                            #13

                            I modified my paintSection function like this:
                            @if(m_orientation == Qt::Horizontal)
                            {
                            //////////////////////////////////////////////////////////////////////////
                            if (!rect.isValid())
                            return;
                            // get the state of the section
                            QStyleOptionHeader opt;
                            initStyleOption(&opt);
                            QStyle::State state = QStyle::State_None;
                            if (isEnabled())
                            state |= QStyle::State_Enabled;
                            if (window()->isActiveWindow())
                            state |= QStyle::State_Active;

                              if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex)
                               opt.sortIndicator = (sortIndicatorOrder() == Qt::AscendingOrder)
                               ? QStyleOptionHeader::SortDown : QStyleOptionHeader::SortUp;
                            
                              // setup the style options structure
                              opt.rect = rect;
                              opt.section = logicalIndex;
                              opt.state |= state;
                            
                              opt.iconAlignment = Qt::AlignVCenter;
                            
                              opt.text = model()->headerData(logicalIndex, m_orientation,
                               Qt::DisplayRole).toString();
                            
                              QPointF oldBO = painter->brushOrigin();
                            
                            
                              // 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;
                            
                              // the selected position
                            
                              // draw the section
                              painter->rotate(90); // Actually the rotation
                              style()->drawControl(QStyle::CE_Header, &opt, painter, this);
                            
                              painter->setBrushOrigin(oldBO);
                              //////////////////////////////////////////////////////////////////////////
                             }
                             else
                              QHeaderView::paintSection (painter,rect,logicalIndex );@
                            

                            And now I need to resize header to it's contents. So how can I resize header to max length string size ? And it's rotates all my header not each item by 90 degree.

                            1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              Anticross
                              wrote on last edited by
                              #14

                              I find solution to draw text by searching a forum:
                              @painter->save();
                              painter->translate(rect.x(), rect.y());
                              painter->rotate(90); // or 270
                              painter->drawText(0, 0, model()->headerData(logicalIndex, m_orientation,Qt::DisplayRole).toString());
                              painter->restore();@
                              "Link":http://developer.qt.nokia.com/faq/answer/how_can_i_draw_vertical_text
                              But if I draw text by this method I lost my header control and get only text. I mean no system styled header and just text on flat panel. And I still need to resize header by it's content.

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                andre
                                wrote on last edited by
                                #15

                                I would modify your previous version of the code (from the post from yesterday) around line 47. What I would do, is first draw a section without text, by modifying the opt variable:

                                @
                                //replacing lines 47 - 50

                                //store the header text
                                QString headerText = opt.text;
                                //reset the header text to no text
                                opt.text = QString();
                                //draw the control (unrotated!)
                                style()->drawControl(QStyle::CE_Header, &opt, painter, this);

                                painter.save();
                                painter->translate(rect.x(), rect.y());
                                painter->rotate(90); // or 270
                                painter->drawText(0, 0, headerText);
                                painter->restore();
                                @

                                That should take care of the actual drawing.

                                As for the re-sizing, I think you need to reimplement sizeHint() to return the right size.

                                1 Reply Last reply
                                0
                                • A Offline
                                  A Offline
                                  Anticross
                                  wrote on last edited by
                                  #16

                                  I write the following code and I have no result. I have a header without any text at all. I think that save and restore functions for painter has no effect after calling drawControl function. So I thinking about some modifications to draw with QStyle::CE_HeaderSection but can't find any typical examples or any other ideas. I tried to draw replacing QStyle::CE_Header by QStyle::CE_HeaderSection and also have no text in header.

                                  1 Reply Last reply
                                  0
                                  • A Offline
                                    A Offline
                                    Anticross
                                    wrote on last edited by
                                    #17

                                    How can I get the painter for each item of my header to rotate it ? This must be the way to solve this task. I also tried to use custom style with same code, but also has no result. ("Style examle":http://developer.qt.nokia.com/faq/answer/how_can_i_display_vertical_text_in_the_section_of_a_qheaderview) It will be useful to have such function for QHeaderView like setVerticalText(bool). Maybe it possible to realize it in next Qt release.

                                    1 Reply Last reply
                                    0
                                    • A Offline
                                      A Offline
                                      Anticross
                                      wrote on last edited by
                                      #18

                                      I found some way to solve this in table widget which I use:
                                      @QHeaderView * header = m_ui->tableWidget->horizontalHeader();

                                      int columnCnt = m_ui->tableWidget->columnCount();
                                      int width = header->width()/columnCnt;
                                      int height = header->height();

                                      for(int i = 0; i<columnCnt; i++)
                                      {
                                      QTableWidgetItem * item = m_ui->tableWidget->horizontalHeaderItem(i);

                                      if(item == NULL)
                                      continue;

                                      QVariant data = item->data(Qt::DisplayRole);

                                      if (data.isValid())
                                      {
                                      QString text=data.toString();
                                      item->setData(Qt::DisplayRole, "");
                                      QPixmap original_button(width, height);
                                      QPainter original_button_painter(&original_button);
                                      /* QHeaderView::paintSection(&original_button_painter, QRect(0, 0, width, height), i);*/

                                      QPixmap pix(width, height);
                                      QPainter p(&pix);
                                      p.drawPixmap(0, 0, original_button);

                                      QRect new_r(0, 0, height, width);
                                      QMatrix m;
                                      m.translate(0, height);
                                      m.rotate(-90);
                                      p.setWorldMatrix(m, true);
                                      p.drawText(new_r, Qt::AlignCenter, text);

                                      item->setIcon(pix);
                                      item->setSizeHint(QSize( height, width ));
                                      }
                                      }@
                                      This code I place on my dialog which holds table widget in ui file. So the only one question is how to set true sizes of the text? It looks smaller then text in vertical header. Waiting for your code critic and propositions.

                                      1 Reply Last reply
                                      0

                                      • Login

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • Users
                                      • Groups
                                      • Search
                                      • Get Qt Extensions
                                      • Unsolved