Qt自定义委托崩溃没有错误代码

Qt Custom Delegate Crash with no error code

本文关键字:错误代码 崩溃 自定义 Qt      更新时间:2023-10-16

我尝试遵循《Qt开发基础》一书中的一个示例来创建自定义委托。

目标是创建一个包含两列的表。第一个是行号。第二列是一个任意的数字,但以条形显示。我刚运行完程序就崩溃了。

下面是我的代码:

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();
}

有什么问题吗?

问题可能出在这两行:

BarDelegate delegate;
Table->setItemDelegateForColumn(1, &delegate);

在堆栈中分配delegate,并将其地址传递给setItemDelegateForColumn函数。然而,一旦执行离开MainWindow构造器的范围,delegate就会被删除。因此,你的表视图得到一个无效的委托。要解决这个问题,你需要使用指向委托的指针。即声明BarDelegate delegate;MainWindow类成员,并且:

delegate = new BarDelegate(this);
Table->setItemDelegateForColumn(1, delegate);