What is the best way to display an animated icon in a QTableView?

后端 未结 5 1433
生来不讨喜
生来不讨喜 2021-02-05 19:54

I\'ve been struggling with this for some times now, and I can\'t seem to find the right way to do this.

What I would like is the ability to use an animated icon as a dec

5条回答
  •  醉话见心
    2021-02-05 20:19

    For the record, I ended up using QAbstractItemView::setIndexWidget from inside the paint method of my delegate, to insert a QLabel displaying the QMovie inside the item (see code below).

    This solution works quite nicely, and keep the display issues separated from the model. One drawback is that the display of a new frame in the label causes the entire item to be rendered again, resulting in almost continuous calls to the delegate's paint method...

    To reduce the overhead inccured by these calls, I tried to minimize the work done for handling movies in the delegate by reusing the existing label if there is one. However, this results in weird behavior when resizing the windows: the animation gets shifted to the right, as if two labels were positioned side by side.

    So well, here is a possible solution, feel free to comment on ways to improve it!

    // Declaration
    
    #ifndef MOVIEDELEGATE_HPP
    #define MOVIEDELEGATE_HPP
    
    #include 
    #include 
    
    
    class QAbstractItemView;
    class QMovie;
    
    
    class MovieDelegate : public QStyledItemDelegate
    {
        Q_OBJECT
    
      public: // member functions
    
        MovieDelegate( QAbstractItemView & view, QObject * parent = NULL );
    
        void paint( QPainter * painter, 
                    const QStyleOptionViewItem & option, 
                    const QModelIndex & index ) const;
    
    
      private: // member functions
    
        QMovie * qVariantToPointerToQMovie( const QVariant & variant ) const;
    
    
      private: // member variables
    
        mutable QAbstractItemView & view_;
    };
    
    #endif // MOVIEDELEGATE_HPP
    
    
    // Definition
    
    #include "movieDelegate.hpp"
    
    #include 
    #include 
    #include 
    #include 
    
    
    Q_DECLARE_METATYPE( QMovie * )
    
    
    //---------------------------------------------------------
    // Public member functions
    //---------------------------------------------------------
    
    MovieDelegate::MovieDelegate( QAbstractItemView & view, QObject * parent )
      : QStyledItemDelegate( parent ), view_( view )
    {
    }
    
    
    void MovieDelegate::paint( QPainter * painter, 
                               const QStyleOptionViewItem & option, 
                               const QModelIndex & index ) const
    {
        QStyledItemDelegate::paint( painter, option, index );
    
        const QVariant & data = index.data( Qt::DecorationRole );
    
        QMovie * movie = qVariantToPointerToQMovie( data );
    
        if ( ! movie )
        {
            view_.setIndexWidget( index, NULL );
        }
        else
        {
            QObject * indexWidget = view_.indexWidget( index );
            QLabel  * movieLabel  = qobject_cast< QLabel * >( indexWidget );
    
            if ( movieLabel )
            {
                // Reuse existing label
    
                if ( movieLabel->movie() != movie )
                {
                    movieLabel->setMovie( movie );
                }
            }
            else
            {
                // Create new label;
    
                movieLabel = new QLabel;
    
                movieLabel->setMovie( movie );
    
                view_.setIndexWidget( index, movieLabel );
            }
        }
    }
    
    
    //---------------------------------------------------------
    // Private member functions
    //---------------------------------------------------------
    
    QMovie * MovieDelegate::qVariantToPointerToQMovie( const QVariant & variant ) const
    {
        if ( ! variant.canConvert< QMovie * >() ) return NULL;
    
        return variant.value< QMovie * >();
    }
    

提交回复
热议问题