Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在QListView中设置列表项边框的动画?_C++_Qt_Qt5_Qlistview_Qstyleditemdelegate - Fatal编程技术网

C++ 如何在QListView中设置列表项边框的动画?

C++ 如何在QListView中设置列表项边框的动画?,c++,qt,qt5,qlistview,qstyleditemdelegate,C++,Qt,Qt5,Qlistview,Qstyleditemdelegate,我正在使用一个QListView和一个从QStyledItemDelegate扩展而来的自定义委托。我重新实现了paint方法,以自定义绘制列表中的每个项目。在“绘制”方法中,我正在列表视图中的选定项周围绘制边框 我希望能够在选择项目时设置项目边框的动画。例如,如果预期的项目边框是5像素,我希望在选择项目时将其从0像素“动画化”到5像素 我最初的想法是连接一个计时器,使其每50毫秒启动一次,并让代理在计时器每次启动时进行绘制,直到绘制完整个边框宽度。但是,代理的重新实现的paint方法是cons

我正在使用一个QListView和一个从QStyledItemDelegate扩展而来的自定义委托。我重新实现了paint方法,以自定义绘制列表中的每个项目。在“绘制”方法中,我正在列表视图中的选定项周围绘制边框

我希望能够在选择项目时设置项目边框的动画。例如,如果预期的项目边框是5像素,我希望在选择项目时将其从0像素“动画化”到5像素

我最初的想法是连接一个计时器,使其每50毫秒启动一次,并让代理在计时器每次启动时进行绘制,直到绘制完整个边框宽度。但是,代理的重新实现的paint方法是const,因此在每次通过paint方法期间,我无法保存或更新border width成员变量


实现这一点的最佳方法是什么?

一种可能的解决方案是创建一个管理项目边框大小的角色,并使用
QVariantAnimation更新它:

#include <QApplication>
#include <QListView>
#include <QPainter>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
#include <QVariantAnimation>

int BorderSizeRole = Qt::UserRole+1;

class AnimationDelegate: public QStyledItemDelegate{
public:
    using QStyledItemDelegate::QStyledItemDelegate;
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{
        QStyledItemDelegate::paint(painter, option, index);

        bool ok;
        int borderSize = index.data(BorderSizeRole).toInt(&ok);
        if(borderSize >0 && ok){
            painter->save();
            QPen pen(QBrush(Qt::red), borderSize);
            painter->setPen(pen);
            painter->drawRect(option.rect);
            painter->restore();
        }
    }
};

class CustomAnimation: public QVariantAnimation{
    QPersistentModelIndex m_index;
    QAbstractItemModel *m_model;
public:
    CustomAnimation(QAbstractItemModel *m_model, QPersistentModelIndex index, QObject *parent=nullptr)
        : QVariantAnimation(parent),
          m_index(index),
          m_model(m_model)
    {
        setStartValue(0);
        setEndValue(5);
        setDuration(50*5);
        connect(this, &CustomAnimation::valueChanged, this, &CustomAnimation::on_valueChanged);
        // delete animation
        start(QAbstractAnimation::DeleteWhenStopped);
    }
private:
    Q_SLOT void on_valueChanged(const QVariant & value){
        if(m_model)
            m_model->setData(m_index, value, BorderSizeRole);
        else
            stop();
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QListView view;
    view.setItemDelegate(new AnimationDelegate(&view));
    QStandardItemModel model;
    for(int i=0; i<10; i++){
        QStandardItem *item = new QStandardItem(QString("item %1").arg(i));
        item->setData(-1, BorderSizeRole);
        model.appendRow(item);
    }
    view.setModel(&model);

    QObject::connect(view.selectionModel(), &QItemSelectionModel::selectionChanged,
                     [&model](const QItemSelection &selected, const QItemSelection & deselected){
        for(const QModelIndex & index: selected.indexes()){
            new CustomAnimation(&model, QPersistentModelIndex(index));
        }
        // remove border
        for(const QModelIndex & index: deselected.indexes()){
            model.setData(index, -1, BorderSizeRole);
        }
    });

    view.show();    
    return a.exec();
}
#包括
#包括
#包括
#包括
#包括
#包括
int BorderSizeRole=Qt::UserRole+1;
类AnimationDelegate:公共QStyledItemDelegate{
公众:
使用QStyledItemDelegate::QStyledItemDelegate;
无效绘制(QPainter*painter,常数QStyleOptionViewItem&option,常数QModelIndex&index)常数{
QStyledItemDelegate::paint(油漆工、选项、索引);
布尔ok;
int borderSize=index.data(BorderSizeRole.toInt)(&ok);
如果(边框大小>0&&ok){
画师->保存();
QPen笔(QBrush(Qt::红色),边框尺寸);
画师->画笔(画笔);
画师->drawRect(选项.rect);
画师->还原();
}
}
};
类CustomAnimation:公共QVariantAnimation{
QPersistentModelIndex m_index;
qabstractemodel*m_模型;
公众:
自定义动画(QBStractItemModel*m_模型,QPersistentModelIndex索引,QObject*parent=nullptr)
:QVariantAnimation(父级),
m_指数(指数),
m_模型(m_模型)
{
设置起始值(0);
setEndValue(5);
设定持续时间(50*5);
连接(此,&CustomAnimation::valueChanged,此,&CustomAnimation::on_valueChanged);
//删除动画
开始(QAbstractAnimation::DeleteWhenStopped);
}
私人:
Q_值上的Q_插槽无效已更改(常数Q变量和值){
if(m_模型)
m_model->setData(m_索引、值、BorderSizeRole);
其他的
停止();
}
};
int main(int argc,char*argv[])
{
质量保证申请a(argc、argv);
QListView视图;
view.setItemDelegate(新建AnimationDelegate(&view));
QS标准模型;
对于(int i=0;isetData(-1,BorderSizeRole);
模型。附录行(项目);
}
view.setModel(&model);
QObject::connect(view.selectionModel(),&QItemSelectionModel::selectionChanged,
[&model](常量QItemSelection&selected,常量QItemSelection&Unselected){
for(常量QModelIndex&index:selected.index()){
新的自定义动画(&模型,QPersistentModelIndex(索引));
}
//删除边框
for(常量QModelIndex&index:diselected.index()){
setData(索引-1,BorderSizeRole);
}
});
view.show();
返回a.exec();
}