我试着按照书中的一个例子来说明#t; Qt Development的基础"创建自定义委托。
目标是创建一个包含两列的表。 第一个是行号。 第二列是一些任意数字,但以条形样式显示。 该程序在运行后如何崩溃。
这是我的代码:
MainWindow类
#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))));
}
}
自定义委托类
#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();
}
有什么问题?
答案 0 :(得分:4)
问题可能出在以下两行:
BarDelegate delegate;
Table->setItemDelegateForColumn(1, &delegate);
您在堆栈中分配delegate
并将其地址传递给setItemDelegateForColumn
函数。但是,只要执行离开delegate
构造函数的范围,就会删除MainWindow
。因此,您的表视图将获得一个无效的委托。要解决此问题,您需要使用指向代理的指针。即将BarDelegate delegate;
声明为MainWindow
类成员并且:
delegate = new BarDelegate(this);
Table->setItemDelegateForColumn(1, delegate);