• 2657阅读
  • 4回复

[提问]如何优化一个QStyledItemDelegate继承类的paint方法 [复制链接]

上一主题 下一主题
离线alexltr
 

只看楼主 倒序阅读 楼主  发表于: 2020-04-20
我有一个model, 其中有一栏数据存储表示图片文件名的字符串,如“1.png;4.png;5.png
现在我想通过用QStyledItemDelegate继承类来将这些图片在TableView中显示出来,主要的代码如下。
但有两个问题请教一下各位:
1. 速度比较慢,请问在代码上是否可以优化?或者这种需求是否有其它更好的解决办法?
2. 怎样更加有效的取得sizeHint?
谢谢!

multiimagesdelegate.h   


  1. #ifndef MULTIIMAGESDELEGATE_H
  2. #define MULTIIMAGESDELEGATE_H
  3. #include <QStyledItemDelegate>
  4. #include <QString>
  5. #include <QObject>
  6. #include <QPainter>
  7. #include <QModelIndex>
  8. #include <QStyle>
  9. #include <QStringList>
  10. #include <QPixmap>
  11. #include <QImage>
  12. #include <QRect>
  13. #include <QSize>
  14. #include <QFile>
  15. class MultiImagesDelegate : public QStyledItemDelegate
  16. {
  17.     Q_OBJECT
  18. public:
  19.     MultiImagesDelegate(QObject *parent = 0);
  20.     MultiImagesDelegate(const QString &imagesFolder, QObject *parent = 0);
  21.     void setImagesFolder(const QString &imagesFolder);
  22.     void paint(QPainter *painter, const QStyleOptionViewItem &option,
  23.                const QModelIndex &index) const override;
  24.     QSize sizeHint(const QStyleOptionViewItem &option,
  25.                    const QModelIndex &index) const override;
  26. private:
  27.      QString mImagesFolder;
  28.      mutable int mWidthHint;
  29.      enum {ImageMargin = 1};
  30. };
  31. #endif


multiimagesdelegate.cpp  


  1. #include "multiimagesdelegate.h"
  2. MultiImagesDelegate::MultiImagesDelegate(QObject *parent) :
  3.     QStyledItemDelegate(parent)
  4. {
  5.     mWidthHint = 200;
  6. }
  7. MultiImagesDelegate::MultiImagesDelegate(const QString &imagesFolder, QObject *parent) :
  8.     QStyledItemDelegate(parent)
  9. {
  10.     setImagesFolder(imagesFolder);
  11. }
  12. //设置图片所在的文件夹
  13. void MultiImagesDelegate::setImagesFolder(const QString &imagesFolder)
  14. {
  15.     mImagesFolder = imagesFolder;
  16. }
  17. void MultiImagesDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
  18.                          const QModelIndex &index) const
  19. {  
  20.     //painter->save();
  21.     painter->setRenderHint(QPainter::Antialiasing);
  22.     //如果是用户选择的行,则用高亮色绘制背景
  23.     if (option.state & QStyle::State_Selected)
  24.         painter->fillRect(option.rect, option.palette.highlight());
  25.     //把model里的图片文件字符串拆分为一个QStringList
  26.     QStringList images = index.data().toString().split(";");
  27.     //绘制每张图片的x位移量,初始值从0开始
  28.     int xOffsetForAdjust = 0;
  29.     QRect optionRect = option.rect;
  30.     //遍历图片文件名,并绘制图片
  31.     for (int i = 0; i < images.count(); ++i) {
  32.         QString imageFileName(mImagesFolder + images.at(i));
  33.         if (QFile(imageFileName).exists()) {
  34.             //加载图片
  35.             QImage individualImage = QImage(imageFileName);
  36.             //按行高对图片进行尺寸调整
  37.             QImage scaledIndividualImage = individualImage.scaledToHeight(optionRect.height());
  38.             //调整后的实际图片宽度和高度
  39.             int scaledWidthOfImage = scaledIndividualImage.width();
  40.             int scaledHeightOfImage = scaledIndividualImage.height();
  41.             //定义绘制图片的矩形
  42.             QRect imageRect(optionRect);
  43.             imageRect.setWidth(scaledWidthOfImage);
  44.             imageRect.setHeight(scaledHeightOfImage);
  45.             //按照已经绘制的图片大小以及当前图片的大小调整当前图片绘制矩形的位置
  46.             imageRect.adjust(xOffsetForAdjust + ImageMargin, ImageMargin * 2,
  47.                              xOffsetForAdjust - ImageMargin, -ImageMargin * 2);
  48.             //把当前图片的宽度加到总的x位移量,用于下一张图片的绘制
  49.             xOffsetForAdjust += scaledWidthOfImage;
  50.             //绘制当前图片
  51.             painter->drawImage(imageRect, scaledIndividualImage);
  52.             //计算所有已经绘制的图片的宽度, 用于sizHint
  53.             int totalWidth = imageRect.right() - optionRect.left() + ImageMargin * 2;
  54.             if (totalWidth > mWidthHint)  //?? 当尺寸变小后,此方法不适用
  55.                 mWidthHint = totalWidth;
  56.         }
  57.     }
  58.     //painter->restore();
  59. }
  60. QSize MultiImagesDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
  61. {
  62.     Q_UNUSED(option);
  63.     Q_UNUSED(index);
  64.     return QSize(mWidthHint,100);
  65. }




我不从事IT,只是喜欢Qt。
我不是程序员,只是与程序有缘。
我写程序,只是为了让工作变得简单有序!

                      ----  一个一直在入门的编程学习者
离线fu22507411

只看该作者 1楼 发表于: 2020-04-20
给图片做缓存
邮箱jiahao_coffee@foxmail.com 有问题可以免费咨询,有空都会回答,不过太难了我答不上来不要介意哈
离线alexltr

只看该作者 2楼 发表于: 2020-04-20
回 fu22507411 的帖子
fu22507411:给图片做缓存 (2020-04-20 13:08) 

谢谢回复。

能麻烦你稍微再具体一点吗?
我不从事IT,只是喜欢Qt。
我不是程序员,只是与程序有缘。
我写程序,只是为了让工作变得简单有序!

                      ----  一个一直在入门的编程学习者
离线dinjay

只看该作者 3楼 发表于: 2020-04-20
model是重写的吧,data函数自义定一个类型,然后return value的时候直接返回qimage对象,delegate里就index()->data()取到的就是qimage对象了,一般托管里不做复杂耗时的数据读写处理。
离线alexltr

只看该作者 4楼 发表于: 2020-04-20
回 dinjay 的帖子
dinjay:
model是重写的吧,data函数自义定一个类型,然后return value的时候直接返回qimage对象,delegate里就index()->data()取到的就是qimage对象了,一般托管里不做复杂耗时的数据读写处理。

是的。 这个我尝试一下。谢谢。
我不从事IT,只是喜欢Qt。
我不是程序员,只是与程序有缘。
我写程序,只是为了让工作变得简单有序!

                      ----  一个一直在入门的编程学习者
快速回复
限100 字节
 
上一个 下一个