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 3.2k 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.
  • VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by
    #2

    it should be really easy, it's just about subclassing QStyledItemDelegate and reimplement paint to paint a rectangle with the level of the battery

    "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

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

      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 2 Replies Last reply
      0
      • 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
        #4

        @mzimmers Hi,

        If you want only to color the background, just return the color from the data() method of your model using the Qt::BackgroundRole, and the percentage value using Qt::DisplayRole.

        1 Reply Last reply
        0
        • 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