[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_OBJECTpublic:
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_OBJECTpublic:
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)