Reputation: 1344
I try to follow an example in the book "Foundations of Qt Development" to create a custom delegate.
The goal is to create a table with two columns. The first is just the row number. The second column is some arbitrary number but show in terms of a bar style. How the program just crashed after I run it.
Here is my code:
The MainWindow Class
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
Table = new QTableView(this);
Model = new QStandardItemModel(this);
dataInit(Model);
Table->setModel(Model);
setCentralWidget(Table);
// If I comment out these two lines
// the program works well
// A table view with number shows
BarDelegate delegate;
Table->setItemDelegateForColumn(1, &delegate);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::dataInit(QStandardItemModel* Model)
{
// Fill the Model with data
for(int r = 1; r < 11; ++r)
{
QStandardItem* item = new QStandardItem(QString("0%1").arg(r));
item->setEditable(false);
Model->setItem(r - 1, 0, item);
Model->setItem(r - 1, 1, new QStandardItem(QString(QString::number(r*17%100))));
}
}
The custom delegate class
#include "bardelegate.h"
BarDelegate::BarDelegate(QObject *parent)
{
}
QSize BarDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
return QSize(30, 15);
}
void BarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
int value = index.model()->data(index, Qt::DisplayRole).toInt();
double factor = (double) value/100.0;
painter->save();
if(factor > 1)
{
painter->setBrush(Qt::red);
factor = 1;
}
else
painter->setBrush(QColor(0, (int)(factor*255), 255-(int)(factor*255)));
painter->setPen(Qt::black);
painter->drawRect(option.rect.x()+2, option.rect.y()+2, (int)(factor*(option.rect.width()-5)), (int)(factor*(option.rect.height()-5)));
painter->restore();
}
What is the problem?
Upvotes: 1
Views: 541
Reputation: 21220
The problem might be in these two lines:
BarDelegate delegate;
Table->setItemDelegateForColumn(1, &delegate);
You allocate delegate
in the stack and pass its address to the setItemDelegateForColumn
function. However delegate
is deleted as soon as the execution leaves the scope of MainWindow
contructor. Thus your table view gets an invalidated delegate. To fix this you need to use a pointer to your delegate. I.e. declare BarDelegate delegate;
as MainWindow
class member and:
delegate = new BarDelegate(this);
Table->setItemDelegateForColumn(1, delegate);
Upvotes: 4