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. Size of icon display in QTableView
Forum Updated to NodeBB v4.3 + New Features

Size of icon display in QTableView

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 2 Posters 2.4k Views 2 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.
  • PerdrixP Offline
    PerdrixP Offline
    Perdrix
    wrote on last edited by Perdrix
    #1

    The icon display appears very small (about 20 pixels wide and 12 tall)

    b302b8cc-d58b-4b10-8354-a43eb25d67a8-image.png

    the Icon file loaded has two versions (one is 32 x 16, the other 64 x 32)

    <qresource prefix="/stacking">
            <file alias="LightColour.png">res/LightColour.png</file>
            <file alias="LightColour@2x.png">res/LightColour@2x.png</file>
             : etc
        </qresource>
    

    which are loaded up as follows:

    if (0 == ImageListModel::icons.size())
    {
         std::lock_guard lock(ImageListModel::mutex);
         if (0 == ImageListModel::icons.size())          // check for race condtion
         {
               ImageListModel::icons.emplace_back(":/stacking/LightColour.png");
                ImageListModel::icons.emplace_back(":/stacking/DarkColour.png");
                      : etc
         }
    }
    

    How can I make the displayed Icon larger than the size it currently is?

    Thanks
    David

    1 Reply Last reply
    0
    • PerdrixP Offline
      PerdrixP Offline
      Perdrix
      wrote on last edited by Perdrix
      #2

      I think I may need a QStyledItemDelegate subclass, a bit like:

      class IconSizeDelegate : public QStyledItemDelegate
      {
      Q_OBJECT

      public:
      	using QStyledItemDelegate::QStyledItemDelegate;
      
      
      protected:
      	void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
      	inline QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
      	{
      		QSize result = QStyledItemDelegate::sizeHint(option, index);
      		result.setHeight(result.height() * 1.2);
      		return result;
      	}
      
      };
      

      The question then is what goes in the paint mf if I want to increase the iconsize for any cells that have a QIcon associated with them (in this case it's all cells in column 0 and that has a selection check box, and Icon and text).

      I know it's not as simple as:

      void IconSizeDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
      	{
      		if (index.data().canConvert<QIcon> ())
      		{
      			QIcon icon = qvariant_cast<QIcon> (index.model()->data(index, Qt::DecorationRole));
      			//scale it . note must be big enough or you get a smaller
      			QSize iconSize = option.decorationSize;
      			iconSize *= 2;
      			QPixmap iconPixmap = icon.pixmap(iconSize);
      			//draw icon
      			painter->drawPixmap(option.rect.x(), option.rect.center().y() - mysize.height() / 2, iconPixmap);
      		}
      	}
      

      and then:

      IconSizeDelegate* iconSizeDelegate{ new IconSizeDelegate() };
      ui->tableView->setItemDelegateForColumn(0, iconSizeDelegate);
      

      Because that didn't work (the column wasn't rendered at all - cells were blank).

      So what should it contain?

      1 Reply Last reply
      0
      • PerdrixP Offline
        PerdrixP Offline
        Perdrix
        wrote on last edited by Perdrix
        #3

        Here's what it looked like before:

        c4abb177-916d-4873-8b02-0616b9d256cb-image.png

        I've had another attempt at the IconSizeDelegate which doesn't quite work (no check box, text formatted without ellipsis :( )

        4b70d9a0-44ef-4f93-9890-94779f467e7e-image.png

        Here's the code that produced the above result:

        void IconSizeDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
        {
        	Q_ASSERT(index.isValid());
        	QStyleOptionViewItem opt{ option };
        	initStyleOption(&opt, index);
        
        	QStyle* style = opt.widget ? opt.widget->style() : QApplication::style();
        	QRect rect = opt.rect;
        
        	constexpr uint neededFeatures
        	{ static_cast<uint>(QStyleOptionViewItem::HasCheckIndicator |
        		QStyleOptionViewItem::HasDisplay |
        		QStyleOptionViewItem::HasDecoration) };
        
        	Q_ASSERT(neededFeatures == (opt.features & neededFeatures));
        		
        	Qt::CheckState state = opt.checkState;
        	QIcon icon = qvariant_cast<QIcon> (index.model()->data(index, Qt::DecorationRole)); 
        	QString text = index.model()->data(index, Qt::DisplayRole).toString();
        
        	painter->save();
        	
        	//
        	// Draw the check box normally
        	//
        	QStyleOptionButton checkBoxStyle;
        	checkBoxStyle.state = (Qt::Checked == state) ? QStyle::State_On : QStyle::State_Off;
        	style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxStyle, painter);
        	//
                // Draw the icon twice as large as the default
        	//
        	QRect nextRect{ rect };
        	nextRect.setLeft(nextRect.left() + checkBoxStyle.rect.width());
        	QSize iconSize = opt.decorationSize;
        	iconSize.scale(2 * iconSize.width(), 2 * iconSize.height(), Qt::KeepAspectRatio);
        	QPixmap iconPixmap{ icon.pixmap(iconSize) };
        	painter->drawPixmap(nextRect.x(), nextRect.center().y() - iconSize.height() / 2, iconPixmap);
        
        	//
        	// Draw the text as normal
        	//
        	nextRect.setLeft(nextRect.left() + iconSize.width());
        	if (option.features & QStyleOptionViewItem::WrapText)
        		painter->drawText(nextRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, text);
        	else
        		painter->drawText(nextRect, Qt::AlignLeft | Qt::AlignVCenter, text);
        	painter->restore();
        }
        

        What have I missed or got wrong? Should I instead have changed option.decorationSize and invoked the base class paint mf? Can the decoration size be over-ridden using a style sheet? There seems to be a sub-element style for this: QStyle::SE_ItemViewItemDecoration

        Thanks
        David

        1 Reply Last reply
        0
        • PerdrixP Offline
          PerdrixP Offline
          Perdrix
          wrote on last edited by
          #4

          Any clues? Thanks David

          M 1 Reply Last reply
          0
          • PerdrixP Perdrix

            Any clues? Thanks David

            M Offline
            M Offline
            mpergand
            wrote on last edited by mpergand
            #5

            @Perdrix said in Size of icon display in QTableView:

            Any clues? Thanks David

            No cos your code is over convoluted ...

            To return to the beginning, drawing an icon with a specific size in a table column, I'm simply doing this:

            case Qt::DecorationRole:
                if(index.column()==Check) return Icon->pixmap(Icon->actualSize(QSize(rowHeight-5,rowHeight-5)));
                break;
            

            rowHeight is the value return by table->verticalHeader()->defaultSectionSize();

            1 Reply Last reply
            0
            • PerdrixP Offline
              PerdrixP Offline
              Perdrix
              wrote on last edited by
              #6

              I'm using a sub-classed QStyledItemDelegate because that's what the documentation says I need to do.

              Where is your code: in the data() mf??

              M 1 Reply Last reply
              0
              • PerdrixP Perdrix

                I'm using a sub-classed QStyledItemDelegate because that's what the documentation says I need to do.

                Where is your code: in the data() mf??

                M Offline
                M Offline
                mpergand
                wrote on last edited by mpergand
                #7

                @Perdrix

                Here the complete source:

                // resizing icon in tableView cell
                #define Check 0
                #define Text 1
                int rowHeight;
                QIcon* Icon;
                
                
                struct Model : public QAbstractTableModel
                {
                
                explicit	Model() : QAbstractTableModel(nullptr) {}
                
                        int	rowCount(const QModelIndex &/*parent*/) const
                            {
                            return 8;
                            }
                
                        int	columnCount(const QModelIndex &/*parent*/) const
                            {
                            return 2;
                            }
                
                    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
                            {
                            if(!index.isValid()) return QVariant();
                            int row=index.row();
                
                            switch (role)
                                {
                                case Qt::DisplayRole:
                                    if(index.column()==Text) return QString("row %1 Col %2").arg(index.row()).arg(index.column());
                                    if(index.column()==Check) return QString("Check box");
                                    break;
                
                                case Qt::CheckStateRole:
                                    if(index.column()==Check) return row%3;
                                    break;
                
                                case Qt::DecorationRole:
                                    if(index.column()==Check) return Icon->pixmap(Icon->actualSize(QSize(rowHeight-5,rowHeight-5)));
                                    break;
                                }
                
                            return QVariant();
                            }
                
                    Qt::ItemFlags flags(const QModelIndex &index) const
                            {Q_UNUSED(index)
                            Qt::ItemFlags f=Qt::ItemIsSelectable|Qt::ItemIsEnabled;
                
                            if(index.column()==Check)
                                f|=Qt::ItemIsUserCheckable;
                
                            return f;
                    }
                };
                
                int main(int argc, char *argv[])
                {
                QApplication app(argc, argv);
                
                    QString path=QDir::homePath()+"/Desktop/Developpement/Qt5.12/Divers/Essai/img/ic32.jpg";
                    Icon=new QIcon(path);
                    qDebug()<<QFile::exists(path)<<path;
                
                    auto table=new QTableView;
                    table->setModel(new Model);
                    rowHeight=table->verticalHeader()->defaultSectionSize();
                    table->horizontalHeader()->setMinimumSectionSize(150);
                    table->resize(400,400);
                    table->show();
                
                return app.exec();
                
                1 Reply Last reply
                0
                • PerdrixP Offline
                  PerdrixP Offline
                  Perdrix
                  wrote on last edited by
                  #8

                  I can see how that works. I would still like to know how one is supposed to do it with a sub-classed QStyledItemDelegate as that is how you're supposed to do it.

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    mpergand
                    wrote on last edited by mpergand
                    #9
                    class ItemDelegate : public QStyledItemDelegate
                    {
                            void    paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                            {
                                QRect rec=option.rect;
                                QSize source=Icon->actualSize(rec.size());
                    
                                 QPixmap pixmap=Icon->pixmap(Icon->actualSize(QSize(rowHeight-5,rowHeight-5)));
                                 QRect target=QRect(rec.topLeft(),source);
                                 target.translate(2,2);
                                 painter->drawPixmap(target, pixmap, QRect(QPoint(0,0),source));
                            }
                    };
                    

                    Added to a third column:
                    table->setItemDelegateForColumn(2,new ItemDelegate);

                    1 Reply Last reply
                    1
                    • PerdrixP Offline
                      PerdrixP Offline
                      Perdrix
                      wrote on last edited by Perdrix
                      #10

                      Hmmphh... I'm quite sure from the other examples I've seen that what you've shown me isn't the "proper way to do it".

                      I got the checkbox display working by changing the checkbox display code:

                      		//
                      		// Draw the check box normally
                      		//
                      		QStyleOptionButton checkBoxStyle;
                      		constexpr int size = 17;
                      		constexpr int space = 6;
                      		checkBoxStyle.rect = QRect(opt.rect.x(),
                      			opt.rect.center().y() - (size / 2),
                      			size,
                      			size);
                      		
                      		checkBoxStyle.state = (Qt::Checked == state) ? QStyle::State_On : QStyle::State_Off;
                      		style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &checkBoxStyle, painter);
                      
                      		//
                      		// Draw the icon twice as large as the default
                      		//
                      		QRect nextRect{ rect };
                      		nextRect.setLeft(nextRect.left() + checkBoxStyle.rect.width() + space);
                      

                      Which I admit is not ideal as it uses hard coded values for the size of the checkbox and the spacing. Surely there's a way to find the default size of a Primitive Element such as a PE_IndicatorItemViewItemCheck???

                      I also still want to know how to get the ellipsis handling for the text done.

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        mpergand
                        wrote on last edited by mpergand
                        #11

                        For elided text see;
                        QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags = 0)

                        Quick test to get the size of a checkbox:

                        QStyle *style = QApplication::style();
                                      QRect r=style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt);
                                      qDebug()<<r.size(); // 19x18 for OSX
                        

                        see here for more infos:
                        https://wiki.qt.io/Center_a_QCheckBox_or_Decoration_in_an_Itemview

                        1 Reply Last reply
                        1
                        • PerdrixP Offline
                          PerdrixP Offline
                          Perdrix
                          wrote on last edited by
                          #12

                          Thank you, that helps enormously!!!

                          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