[SOLVED]Custom widget's position is incorrect in QItemDelegate after removed item from QTableView



  • Hi all,
    I met a problem when use QTableView and QItemDelegate:
    I added a custom widget in QItemDelegate, and i wanna the widget is always open, so i use openPersistantEditor to open the widgets when the tableview is constructed.
    everything works well except sometimes i remove item from the tableview.
    when i scroll the tableview to bottom, and remove the last item, then, the widgets' position is incorrect.
    i don't know why.
    here is code and screen shot.
    pls. give me a hand.
    thank u.

    downloadingitem.h:
    @#ifndef DOWNLOADINGITEM_H
    #define DOWNLOADINGITEM_H

    #include <QWidget>
    #include <QDebug>
    #include <QModelIndex>
    namespace Ui {
    class DownloadingItem;
    }

    class DownloadingItem : public QWidget
    {
    Q_OBJECT

    public:
    explicit DownloadingItem(QWidget *parent = 0);
    ~DownloadingItem();

    void setItemIndex(const QModelIndex& index);
    void setItemIcon(QString url);
    void setItemName(QString name);
    void setItemSize(qint64 size);
    void setItemVersion(QString version);
    void setItemProgress(int progress);
    void setItemDownloadedSize(qint64 size);
    void setItemSpeed(qint64 speed);
    void setItemStatus(int status);
    

    signals:
    void startButtonClicked();
    void removeButtonClicked();
    void pauseButtonClicked();

    private slots:
    void on_startButton_clicked();

    void on_removeButton_clicked();
    
    void on_pauseButton_clicked();
    

    private:
    Ui::DownloadingItem *ui;
    QModelIndex m_index;
    };

    #endif // DOWNLOADINGITEM_H
    @

    downloadingitem.cpp
    @#include "downloadingitem.h"
    #include "ui_downloadingitem.h"
    DownloadingItem::DownloadingItem(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::DownloadingItem)
    {
    ui->setupUi(this);
    //setAttribute(Qt::WA_TranslucentBackground, false);
    //setStyleSheet("background:transparent;");
    }

    DownloadingItem::~DownloadingItem()
    {
    delete ui;
    }

    void DownloadingItem::setItemIndex(const QModelIndex &index)
    {
    m_index = index;
    }

    void DownloadingItem::setItemIcon(QString url)
    {
    //ui->iconLabel->setPixmap(QPixmap(url));
    }

    void DownloadingItem::setItemName(QString name)
    {
    // ui->nameLabel->setText(name);
    }

    void DownloadingItem::setItemSize(qint64 size)
    {
    // ui->sizeLabel->setText(QString::number(size));
    }

    void DownloadingItem::setItemVersion(QString version)
    {
    // ui->versionLabel->setText(version);
    }

    void DownloadingItem::setItemProgress(int progress)
    {
    // ui->progressBar->setValue(progress);
    }

    void DownloadingItem::setItemDownloadedSize(qint64 size)
    {
    // ui->downloadedSizeLabel->setText(QString::number(size));
    }

    void DownloadingItem::setItemSpeed(qint64 speed)
    {
    // ui->speedLabel->setText(QString::number(speed));
    }

    void DownloadingItem::setItemStatus(int status)
    {
    // switch (status)
    // {
    // case 0:
    // case 1:
    // ui->startButton->setEnabled(false);
    // ui->pauseButton->setEnabled(true);
    // break;
    // case 2:
    // case 3:
    // ui->startButton->setEnabled(true);
    // ui->pauseButton->setEnabled(false);
    // break;
    // case 4:
    // ui->startButton->setEnabled(false);
    // ui->pauseButton->setEnabled(false);
    // break;
    // }
    }

    void DownloadingItem::on_startButton_clicked()
    {
    qDebug() << m_index << "is clicked" << endl;
    emit startButtonClicked();
    }

    void DownloadingItem::on_removeButton_clicked()
    {
    emit removeButtonClicked();
    }

    void DownloadingItem::on_pauseButton_clicked()
    {
    emit pauseButtonClicked();
    }
    @

    and the header for delegate:
    @#ifndef INSTALLEDAPPDELEGATE_H
    #define INSTALLEDAPPDELEGATE_H

    #include <QItemDelegate>

    class InstalledAppDelegate : public QItemDelegate
    {
    Q_OBJECT

    public:
    InstalledAppDelegate(QObject *parent=0);

    void paint(QPainter *painter, const QStyleOptionViewItem &option,
               const QModelIndex &index) const;
    
    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
    
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
                          const QModelIndex &index) const;
    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const;
    

    private slots:
    void handleStartButtonClicked();
    void handleRemoveButtonClicked();
    void handlePauseButtonClicked();
    };

    #endif // INSTALLEDAPPDELEGATE_H
    @



  • and cpp for delegate
    @#include "installedappdelegate.h"
    #include <QDebug>
    #include <QPainter>
    #include <QStyleOptionButton>
    #include <QApplication>
    #include <QCheckBox>
    #include "downloadingitem.h"
    InstalledAppDelegate::InstalledAppDelegate(QObject *parent)
    : QItemDelegate(parent)
    {
    }

    void InstalledAppDelegate::paint(QPainter *painter,
    const QStyleOptionViewItem &option,
    const QModelIndex &index) const
    {
    bool checked = index.model()->data(index, Qt::CheckStateRole).toBool();
    if (checked)
    {
    painter->save();
    painter->drawImage(option.rect, QImage("select.png"));
    painter->restore();
    }
    if (index.column() == 1)
    {
    QString name = index.model()->data(index, Qt::UserRole+1).toString();
    QString icon = index.model()->data(index, Qt::UserRole+2).toString();
    painter->save();
    painter->drawImage(option.rect.x() + 8, option.rect.y() + 7, QImage(icon));
    painter->drawText(option.rect.x()+68, option.rect.y()+35, name);
    painter->restore();
    }
    else if (index.column() == 0)
    {
    painter->save();
    painter->drawImage(option.rect.x() + 5, option.rect.y() + 25, QImage("checkbox.png"));
    if (checked)
    {
    painter->drawImage(option.rect.x() + 5, option.rect.y() + 25, QImage("checked.png"));
    }
    painter->restore();
    }

    }

    QSize InstalledAppDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    //return QSize(100, 150);
    }

    QWidget *InstalledAppDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
    {
    if (index.column() == 2)
    {
    DownloadingItem *item = new DownloadingItem(parent);
    item->setItemIndex(index);
    connect(item, SIGNAL(pauseButtonClicked()),
    this, SLOT(handlePauseButtonClicked()));
    connect(item, SIGNAL(removeButtonClicked()),
    this, SLOT(handleRemoveButtonClicked()));
    connect(item, SIGNAL(startButtonClicked()),
    this, SLOT(handleStartButtonClicked()));
    return item;
    }
    return NULL;
    }

    void InstalledAppDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    {
    }

    void InstalledAppDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    {
    }

    void InstalledAppDelegate::handleStartButtonClicked()
    {
    qDebug() << "start button clicked" << endl;
    }

    void InstalledAppDelegate::handleRemoveButtonClicked()
    {
    qDebug() << "remove button clicked" << endl;
    }

    void InstalledAppDelegate::handlePauseButtonClicked()
    {
    qDebug() << "pause button clicked" << endl;
    }
    @

    model.h
    @#ifndef INSTALLEDAPPMODEL_H
    #define INSTALLEDAPPMODEL_H

    #include <QAbstractTableModel>
    #include <QItemSelectionModel>
    #include <QStringList>
    class InstalledAppModel : public QAbstractTableModel
    {
    Q_OBJECT
    public:
    enum InstalledAppModelRole
    {
    AppName = Qt::UserRole + 1,
    AppIcon,
    AppLatestVer,
    AppVer,
    AppSize,
    DocSize
    };
    explicit InstalledAppModel(QObject *parent = 0);
    void Remove();
    QVariant data(const QModelIndex &index, int role) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role);
    int rowCount(const QModelIndex &parent) const;
    int columnCount(const QModelIndex &parent) const;

    void changeName();
    void changeChecked();
    void setSelectionModel(QItemSelectionModel *model);
    

    signals:

    public slots:
    private slots:
    void handleSelectionChanged(QItemSelection, QItemSelection);
    private:
    QStringList m_name;
    bool m_checked;
    QItemSelectionModel *m_selectionModel;
    int m_rowCount;
    };

    #endif // INSTALLEDAPPMODEL_H
    @



  • model.cpp
    @#include "installedappmodel.h"
    #include <QDebug>
    InstalledAppModel::InstalledAppModel(QObject *parent) :
    QAbstractTableModel(parent), m_rowCount(20)
    {
    // m_name = QString::fromLocal8Bit("天地霹雳游侠");
    m_checked = false;
    // m_selectionModel = new QItemSelectionModel(this);
    // connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
    // this, SLOT(handleSelectionChanged(QItemSelection, QItemSelection)));
    for (int i = 0; i < 20; ++i)
    {
    beginInsertRows(QModelIndex(), 0, 0);
    m_name << QString::number(i);
    endInsertRows();
    }
    }

    void InstalledAppModel::Remove()
    {
    qDebug() << "installed app model remove" << endl;
    beginRemoveRows(QModelIndex(), 0, 0);
    m_name.pop_front();
    endRemoveRows();
    }

    QVariant InstalledAppModel::data(const QModelIndex &index, int role) const
    {
    if (!index.isValid())
    return QVariant();

    switch (role)
    {
    case AppName:
        return m_name[index.row()];
    case AppIcon:
        return QString("app.png");
    case Qt::CheckStateRole:
        return m_selectionModel->isSelected(index);
    }
    
    return QVariant();
    

    }

    bool InstalledAppModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
    if (!index.isValid())
    return false;
    switch (index.column())
    {
    case 0:
    if (role == Qt::CheckStateRole)
    {
    m_checked = value.toBool();
    }
    break;
    }
    emit dataChanged(this->index(0, 0), this->index(rowCount(QModelIndex())-1, columnCount(QModelIndex())-1));
    return true;
    }

    int InstalledAppModel::rowCount(const QModelIndex &parent) const
    {
    return m_name.count();
    }

    int InstalledAppModel::columnCount(const QModelIndex &parent) const
    {
    return 4;
    }

    void InstalledAppModel::changeName()
    {
    //m_name = "my name";
    emit dataChanged(index(0, 1), index(3, 1));
    }

    void InstalledAppModel::changeChecked()
    {
    m_checked = !m_checked;
    emit dataChanged(this->index(0, 0), this->index(3, 0));
    }

    void InstalledAppModel::setSelectionModel(QItemSelectionModel *model)
    {
    m_selectionModel = model;
    connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
    this, SLOT(handleSelectionChanged(QItemSelection, QItemSelection)));
    }

    void InstalledAppModel::handleSelectionChanged(QItemSelection select, QItemSelection deselect)
    {
    emit dataChanged(this->index(0, 0), this->index(rowCount(QModelIndex())-1, columnCount(QModelIndex())-1));
    }
    @



  • anybody can help me ?



  • nobody,nobody? but u?



  • Solved!
    added this statement:
    m_tableview->setVerticalScrollModel(ScrollPerIndex)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.