我有一个自定义委托,它被添加到
QTableView
的第一列。代码如下。 我在表视图上的复选框遇到奇怪的渲染问题。当选中所有可见的复选框时,复选框会正确渲染。但是,当取消选中两个或多个复选框时,该复选框将无法正确显示。请看下面的例子:
全部检查:
一些未检查的:
任意取消选中/选中复选框总是会重新捕获此行为。奇怪的是,在复选框未正确渲染的情况下,白色复选标记会闪烁,就好像它被部分重绘但未完全扩展一样。
委托子类如下:
#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);
}
任何对此的想法将不胜感激!
对我来说,当我使用您的
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);
}
对我来说,结果如下: