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. [SOLVED] Modify QTableWidget's paintEvent()
Qt 6.11 is out! See what's new in the release blog

[SOLVED] Modify QTableWidget's paintEvent()

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 9.2k Views 1 Watching
  • 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.
  • D Offline
    D Offline
    d2uriel
    wrote on last edited by
    #1

    Hello,

    First of all - Happy New Year ;-)

    I'm using a QTableWidget (actually a class based on it) and instances of QTableWidgetItem (also subclassed) in my application. I have a problem modifying QTableWidget's paintEvent(). I'd like to add to the copied cells a rectangle made of Qt::DashDotLine. This is actually my first try to alter ways of stuff being painted on the screen and probably that's why I have no idea how to work with it.

    Code:
    @void myTable::paintEvent(QPaintEvent e)
    {
    QTableWidget::paintEvent(e);
    for(int r = 0; r < rowCount(); r++)
    {
    for(int c = 0; c < columnCount(); c++)
    {
    if(((myCell
    )itemAt(r, c))->isCopied())
    {
    QPainter p(this);
    p.setPen(QPen(Qt::cyan, Qt::DashDotLine));
    p.setBrush(QBrush(Qt::cyan));
    int x = columnViewportPosition(c);
    int y = rowViewportPosition(r);
    int w = columnWidth(c);
    int h = rowHeight(r);
    p.drawRect(QRect(columnViewportPosition(c) + 2, rowViewportPosition(r) + 2, columnWidth(c) - 4, rowHeight(r) - 4));
    }
    }
    }
    }@
    So as you can see first of all I run the default paintEvent() of the widget and then try to apply some changes. I go through all items in the table and check if their copied flag is set to true (this is the only modification I made to QTableWidgetItem class - added that flag ;-) ). If it's true I'd like to paint the rectangle I was talking about.

    What am I doing wrong?

    Thank you in advance for your help,

    Daniel.

    "Do not judge, and you will never be mistaken." - Jean-Jacques Rousseau

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

      The actual painting of individual cells is done in an "item delegate":/doc/qt-4.8/model-view-programming.html#delegate-classes. The standard delegate for all Qt builtin item view and item widgets is [[Doc:QStyledItemDelegate]]. I recommend subclassing this one and reimplement its paint method. You can get the data from the QTableWidgetItem by using the data() method on the index passed to paint().

      http://www.catb.org/~esr/faqs/smart-questions.html

      1 Reply Last reply
      0
      • D Offline
        D Offline
        d2uriel
        wrote on last edited by
        #3

        Well, it seemed pretty easy as I read what you wrote. It probably is if you know the Model/View programming concept. Since I don't know it and I've spent over two hours trying to find a solution I will ask for your help again.

        I am trying to do what you suggested. The way I wanted to use in my first post gave me access to myCell's object isCopied() method. I have no idea how to access it from the delegate I created (from it's paint() method actually). There's only 3 parameters to this method: a QPainter, a QStyleOptionViewItem and a QModelIndex.

        How can I access isCopied() method of a modified QTableWidgetItem from my delegates paint() method?

        I know I should have read the whole documentation and start from the basics... please don't throw stones at me for that.

        "Do not judge, and you will never be mistaken." - Jean-Jacques Rousseau

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

          I would make the implementation of the isCopied() property based on the item views data()/setData() methods. You can start with this sketch:

          In the header of your table widget item subclass add:

          @
          enum MyItemRoles { IsCopiedRole = Qt::UserRole };
          @

          Then change the implementation of isCopied() to:

          @
          bool MyTableWidgetItem::isCopied() const
          {
          QVariant v = data(IsCopiedRole);
          if(v.isValid())
          return v.toBool();
          else
          return false;
          }

          void MyTableWidgetItem::setIsCopied(bool copied)
          {
          setData(UserRole, copied);
          }
          @

          This changes make your implementation use the internal storage already provided by QTableWidgetItem while keeping your sources compatible with the current implementation.

          In your delegate (and in any other spot where you only have a [[Doc:QModelIndex]] at hand, use the following snippet to retrieve the value:

          @
          // assuming you inherit from QStyledItemDelegate

          void MyItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
          {
          // call the base class paint method first
          QStyledItemDelegate::paint(painter, option, index);

          // is the current index a copy?
          QVariant isCopyVariant = index.data(MyTableWidgetItem::IsCopiedRole);
          bool isCopied = isCopyVariant.isValid() ? isCopyVariant.toBool() : false;
          
          // your additional drawing code goes here...
          
          if(isCopied) {
              // save the painter's state
              painter->save();
          
              // translate the painter's origin
              painter->translate( option.rect.topLeft() );
          
              // set the painter's pen & brush
              painter->setPen(QPen(Qt::cyan, Qt::DashDotLine));
              painter->setBrush(QBrush(Qt::cyan));
          
              // get the rect of the item to draw:
              QRect rect = option.rect;
          
              // adjust the rect to your needs
              rect.adjust(2, 2, -4, -4);
          
              painter.drawRect(rect);
          
              // restore the painter's state
              painter->restore();
          }
          

          }
          @

          This is from brain to terminal - no guarantee to error-free compilation, but you should get the big picture.

          http://www.catb.org/~esr/faqs/smart-questions.html

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

            What you might do, is to make sure that you define your own data role that will provide that information for your item. You can access the data from the item using the QModelIndex.

            1 Reply Last reply
            0
            • D Offline
              D Offline
              d2uriel
              wrote on last edited by
              #6

              Aah, alright. That's brilliant. I really have to read about and learn Model/View architecture. Thank you very much Volker and Andre. I actually had a look at data() and setData() methods but after a short read, for some reason, I decided they won't help me ;-).

              Once again - thank you!

              "Do not judge, and you will never be mistaken." - Jean-Jacques Rousseau

              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