`QItemDelegateClass::drawCheck` (QPainter) 的渲染问题

问题描述 投票:0回答:1

我有一个自定义委托,它被添加到

QTableView
的第一列。代码如下。 我在表视图上的复选框遇到奇怪的渲染问题。当选中所有可见的复选框时,复选框会正确渲染。但是,当取消选中两个或多个复选框时,该复选框将无法正确显示。请看下面的例子:

全部检查:

enter image description here

一些未检查的:

enter image description here

任意取消选中/选中复选框总是会重新捕获此行为。奇怪的是,在复选框未正确渲染的情况下,白色复选标记会闪烁,就好像它被部分重绘但未完全扩展一样。

委托子类如下:

#ifndef BOOLEANITEMDELEGATE_H
#define BOOLEANITEMDELEGATE_H

#include <QItemDelegate>
#include <QSqlTableModel>

class BooleanItemDelegate : public QItemDelegate
{

public:
    BooleanItemDelegate(QSqlTableModel* model, QObject* parent);
    ~BooleanItemDelegate();

public:
    void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex& index) const;
    bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
};

#endif // BOOLEANITEMDELEGATE_H
#include "BooleanItemDelegate.h"
#include <qcoreevent.h>

BooleanItemDelegate::BooleanItemDelegate(QSqlTableModel* model, QObject* parent)
    : QItemDelegate(parent)
{}


BooleanItemDelegate::~BooleanItemDelegate()
{}

void BooleanItemDelegate::paint(
    QPainter* painter,
    const QStyleOptionViewItem& option,
    const QModelIndex& index
) const
{
    drawBackground(painter, option, index);
    drawCheck(painter, option, option.rect, index.data().toBool() ? Qt::Checked : Qt::Unchecked);
    drawFocus(painter, option, option.rect);
}


bool BooleanItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
{
    if (event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick )
    {
        model->setData(index, !model->data(index).toBool());
        event->accept();
    }
    return QItemDelegate::editorEvent(event, model, option, index);
}

任何对此的想法将不胜感激!

qt qpainter qcheckbox qitemdelegate
1个回答
0
投票

对我来说,当我使用您的

paint
方法的实现时,数据会正确呈现。问题可能出在其他地方。

解决方案

我建议尝试完全实现委托:

CheckboxDelegate.cpp

#include "CheckboxDelegate.h"
#include <QCheckBox>

CheckboxDelegate::CheckboxDelegate(QObject *parent) :
    QItemDelegate{parent}
{

}

void CheckboxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    drawBackground(painter, option, index);
    drawCheck(painter, option, option.rect, index.data().toBool() ? Qt::Checked : Qt::Unchecked);
    drawFocus(painter, option, option.rect);
}

QWidget *CheckboxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const
{
    return new QCheckBox(parent);
}

void CheckboxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
{
    editor->move(option.rect.center() - QPoint(8, 8));
    editor->resize(16, 16);
}

void CheckboxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    static_cast<QCheckBox *>(editor)->setCheckState(index.data().toBool() ? Qt::Checked : Qt::Unchecked);
}

void CheckboxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    model->setData(index, static_cast<QCheckBox *>(editor)->checkState() == Qt::Checked);
}

您可以像这样测试委托:

主窗口.cpp

#include "MainWindow.h"
#include "CheckboxDelegate.h"
#include <QStandardItemModel>
#include <QTableView>
#include <QBoxLayout>

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent)
{
    auto *model{new QStandardItemModel(this)};
    auto *view{new QTableView(this)};
    auto *l{new QVBoxLayout(this)};

    for (int n{0}; n < 10; n++)
        model->appendRow(new QStandardItem(QString::number(n < 5)));

    view->setModel(model);
    view->setFrameStyle(QTableView::NoFrame);
    view->setItemDelegateForColumn(0, new CheckboxDelegate(this));
    view->setEditTriggers(QTableView::CurrentChanged);

    l->addWidget(view);
    l->setContentsMargins(0, 0, 0, 0);

    resize(640, 480);
}

结果

对我来说,结果如下:

Application window with a one-column table with checkboxes

© www.soinside.com 2019 - 2024. All rights reserved.