Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. General talk
  3. Brainstorm
  4. want to add a graphic to a table
Forum Updated to NodeBB v4.3 + New Features

want to add a graphic to a table

Scheduled Pinned Locked Moved Unsolved Brainstorm
14 Posts 6 Posters 2.9k Views 4 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.
  • mzimmersM mzimmers

    Heh...the words "Qt," "easy" and "mzimmers" don't often collide in the same sentence.

    I couldn't find an example with the word QStyledItemDelegate, so I've looked at the docs. So, do I create a QModelIndex, and somehow set the delegate onto that?

    Originally I was thinking of using a (readonly) QProgressBar for this, but that's probably overkill. I could just color the background and express the power level as a percentage.

    Gojir4G Offline
    Gojir4G Offline
    Gojir4
    wrote on last edited by Gojir4
    #5

    @mzimmers
    Here is an example of reimplementation of a QStyledItemDelegate drawing a progress bar using QStyleOptionProgressBar. It may help you to make your own custom delegate. I think this is pretty close to what you are trying to achieve

    //.h
    #ifndef PROGRESSBARITEMDELEGATE_H
    #define PROGRESSBARITEMDELEGATE_H
    
    #include <QStyledItemDelegate>
    
    class ABSTRACTTASK_SHARED_EXPORT ProgressBarItemDelegate : public QStyledItemDelegate
    {
    public:
        ProgressBarItemDelegate(QObject *parent = 0);
        ~ProgressBarItemDelegate();
    
        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
    
    protected:
        virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
    
    
    };
    
    #endif // PROGRESSBARITEMDELEGATE_H
    //.cpp
    #include "progressbaritemdelegate.h"
    #include "taskfuturemodel.h"
    
    #include <QAbstractItemView>
    #include <QApplication>
    #include <QDebug>
    #include <QFontMetrics>
    
    ProgressBarItemDelegate::ProgressBarItemDelegate(QObject *parent) :
        QStyledItemDelegate(parent){}
    
    ProgressBarItemDelegate::~ProgressBarItemDelegate() {}
    
    QSize ProgressBarItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        QSize sizeHint = QStyledItemDelegate::sizeHint(option, index);
        QFont font;
        QFontMetrics fm(font);
        int width = qMax(20, fm.width(index.data(MyModel::ProgressTextRole).toString()));
        //qDebug() << "ProgressBarItemDelegate::sizeHint: " << sizeHint;
        sizeHint.setWidth(width);
        //qDebug() << "ProgressBarItemDelegate::sizeHint updated: " << sizeHint;
    
        return sizeHint;
    }
    
    void ProgressBarItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    
        //Possible alternative using stylesheet
        //https://stackoverflow.com/questions/10630360/customized-color-on-progressbar-delegate
        if (index.column() == MyModel::COL_PROGRESS_VALUE) {
            int progress = index.data().toInt();
            bool failed = progress == -2;
            int min = 0;
            //Set undeterminate progress in case of -1 value
            int max = progress == -1 ? 0 : 100;
            QString result;
    
            //Get min & max values from the model data
            const QAbstractItemModel *model = view->model();
            if(model){
                min = index.data(MyModel::ProgressMinRole).toInt();
                max = index.data(MyModel::ProgressMaxRole).toInt();
                result = index.data(MyModel::ResultRole).toString();
            }
            
            if(result == "Failed")
                failed = true;
            QString progressText = index.data(TaskFutureModel::ProgressTextRole).toString();
    
            QStyleOptionProgressBar progressBarOption;
            progressBarOption.rect = option.rect;
            progressBarOption.minimum = min;
            progressBarOption.maximum = max;
            progressBarOption.progress = qMin(progress, progressBarOption.maximum);
    
            progressBarOption.text = progressText;
            progressBarOption.textVisible = true;
            progressBarOption.textAlignment = Qt::AlignCenter;
            if(failed || result == "Failed"){
                progressBarOption.palette.setColor(QPalette::Highlight, QColor("red"));
            } else if(result == "Aborted"){
                progressBarOption.palette.setColor(QPalette::Highlight, QColor("orange"));
            } else {
                progressBarOption.palette.setColor(QPalette::Highlight, QColor("#blue"));
            }
    
            if((min == 0 && max == 0 )|| progress == -1){
                progressBarOption.palette.setColor(QPalette::HighlightedText, QColor("white"));
                progressBarOption.palette.setColor(QPalette::WindowText, QColor("white"));
            }
    
            QApplication::style()->drawControl(QStyle::CE_ProgressBar,
                                               &progressBarOption, painter);
        } else
            QStyledItemDelegate::paint(painter, option, index);
    }
    

    Usage:

    ui->tvTasks->setItemDelegateForColumn(<Column_Index>,
                                              new ProgressBarItemDelegate(myTableView));
    
    mzimmersM 1 Reply Last reply
    2
    • Gojir4G Gojir4

      @mzimmers
      Here is an example of reimplementation of a QStyledItemDelegate drawing a progress bar using QStyleOptionProgressBar. It may help you to make your own custom delegate. I think this is pretty close to what you are trying to achieve

      //.h
      #ifndef PROGRESSBARITEMDELEGATE_H
      #define PROGRESSBARITEMDELEGATE_H
      
      #include <QStyledItemDelegate>
      
      class ABSTRACTTASK_SHARED_EXPORT ProgressBarItemDelegate : public QStyledItemDelegate
      {
      public:
          ProgressBarItemDelegate(QObject *parent = 0);
          ~ProgressBarItemDelegate();
      
          QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
      
      protected:
          virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
      
      
      };
      
      #endif // PROGRESSBARITEMDELEGATE_H
      //.cpp
      #include "progressbaritemdelegate.h"
      #include "taskfuturemodel.h"
      
      #include <QAbstractItemView>
      #include <QApplication>
      #include <QDebug>
      #include <QFontMetrics>
      
      ProgressBarItemDelegate::ProgressBarItemDelegate(QObject *parent) :
          QStyledItemDelegate(parent){}
      
      ProgressBarItemDelegate::~ProgressBarItemDelegate() {}
      
      QSize ProgressBarItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
      {
          QSize sizeHint = QStyledItemDelegate::sizeHint(option, index);
          QFont font;
          QFontMetrics fm(font);
          int width = qMax(20, fm.width(index.data(MyModel::ProgressTextRole).toString()));
          //qDebug() << "ProgressBarItemDelegate::sizeHint: " << sizeHint;
          sizeHint.setWidth(width);
          //qDebug() << "ProgressBarItemDelegate::sizeHint updated: " << sizeHint;
      
          return sizeHint;
      }
      
      void ProgressBarItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
      {
      
          //Possible alternative using stylesheet
          //https://stackoverflow.com/questions/10630360/customized-color-on-progressbar-delegate
          if (index.column() == MyModel::COL_PROGRESS_VALUE) {
              int progress = index.data().toInt();
              bool failed = progress == -2;
              int min = 0;
              //Set undeterminate progress in case of -1 value
              int max = progress == -1 ? 0 : 100;
              QString result;
      
              //Get min & max values from the model data
              const QAbstractItemModel *model = view->model();
              if(model){
                  min = index.data(MyModel::ProgressMinRole).toInt();
                  max = index.data(MyModel::ProgressMaxRole).toInt();
                  result = index.data(MyModel::ResultRole).toString();
              }
              
              if(result == "Failed")
                  failed = true;
              QString progressText = index.data(TaskFutureModel::ProgressTextRole).toString();
      
              QStyleOptionProgressBar progressBarOption;
              progressBarOption.rect = option.rect;
              progressBarOption.minimum = min;
              progressBarOption.maximum = max;
              progressBarOption.progress = qMin(progress, progressBarOption.maximum);
      
              progressBarOption.text = progressText;
              progressBarOption.textVisible = true;
              progressBarOption.textAlignment = Qt::AlignCenter;
              if(failed || result == "Failed"){
                  progressBarOption.palette.setColor(QPalette::Highlight, QColor("red"));
              } else if(result == "Aborted"){
                  progressBarOption.palette.setColor(QPalette::Highlight, QColor("orange"));
              } else {
                  progressBarOption.palette.setColor(QPalette::Highlight, QColor("#blue"));
              }
      
              if((min == 0 && max == 0 )|| progress == -1){
                  progressBarOption.palette.setColor(QPalette::HighlightedText, QColor("white"));
                  progressBarOption.palette.setColor(QPalette::WindowText, QColor("white"));
              }
      
              QApplication::style()->drawControl(QStyle::CE_ProgressBar,
                                                 &progressBarOption, painter);
          } else
              QStyledItemDelegate::paint(painter, option, index);
      }
      

      Usage:

      ui->tvTasks->setItemDelegateForColumn(<Column_Index>,
                                                new ProgressBarItemDelegate(myTableView));
      
      mzimmersM Offline
      mzimmersM Offline
      mzimmers
      wrote on last edited by
      #6

      @Gojir4 thank you so much for the example. I've copied your code into my project. I'm getting an error about ABSTRACTTASK_SHARED_EXPORT, and I can't find anything online about that keyword. Can you tell me what it's used for?

      Gojir4G 1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #7

        Hi,

        It's a custom macro based on the Creating Shared Libraries chapter in Qt's documentation.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        2
        • mzimmersM Offline
          mzimmersM Offline
          mzimmers
          wrote on last edited by
          #8

          Oh, OK, so I can probably skip it, then?

          mrjjM 1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #9

            If you have that class directly in your application project, yes.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            1
            • mzimmersM mzimmers

              @Gojir4 thank you so much for the example. I've copied your code into my project. I'm getting an error about ABSTRACTTASK_SHARED_EXPORT, and I can't find anything online about that keyword. Can you tell me what it's used for?

              Gojir4G Offline
              Gojir4G Offline
              Gojir4
              wrote on last edited by
              #10

              @mzimmers Sorry I forgot to remove this keyword from my code.

              1 Reply Last reply
              0
              • mzimmersM mzimmers

                Oh, OK, so I can probably skip it, then?

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #11

                @mzimmers
                Just as a note.
                Very small small sample of delegate here.
                https://forum.qt.io/topic/96545/insert-fill-circle-into-cell-of-qtablewidget/8
                notice VRonin comment.

                1 Reply Last reply
                3
                • VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #12

                  One more note: This QAbstractItemView *view = qobject_cast<QAbstractItemView *>(parent()); is unsafe as hell. Nothing says the delegate should be a child of the view. in fact you can use the same delegate in multiple views. the correct way to get the model is index.model() without passing from the view

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  kshegunovK Gojir4G 2 Replies Last reply
                  1
                  • VRoninV VRonin

                    One more note: This QAbstractItemView *view = qobject_cast<QAbstractItemView *>(parent()); is unsafe as hell. Nothing says the delegate should be a child of the view. in fact you can use the same delegate in multiple views. the correct way to get the model is index.model() without passing from the view

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by
                    #13

                    @VRonin said in want to add a graphic to a table:

                    in fact you can use the same delegate in multiple views.

                    You shouldn't though. There's a warning in the docs about it. I second your parent warning, however, it's quite correct as the view does not take ownership of the delegate.

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    1
                    • VRoninV VRonin

                      One more note: This QAbstractItemView *view = qobject_cast<QAbstractItemView *>(parent()); is unsafe as hell. Nothing says the delegate should be a child of the view. in fact you can use the same delegate in multiple views. the correct way to get the model is index.model() without passing from the view

                      Gojir4G Offline
                      Gojir4G Offline
                      Gojir4
                      wrote on last edited by
                      #14

                      @VRonin said in want to add a graphic to a table:

                      One more note: This QAbstractItemView *view = qobject_cast<QAbstractItemView *>(parent()); is unsafe as hell. Nothing says the delegate should be a child of the view. in fact you can use the same delegate in multiple views. the correct way to get the model is index.model() without passing from the view

                      Thanks for signaling the issue. I have fixed my sample code above.

                      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