【发布时间】:2019-10-08 17:55:02
【问题描述】:
我已经编写了一个自定义数据模型来显示几个 QTableView。
从技术上讲,一切正常:我的视图显示了我的模型所做的更改。我的数据模型是可编辑的,setData() 方法确实会发出dataChanged() 信号并在成功编辑时返回true。
但是,我的问题是我必须将鼠标移到 QTableView 上才能显示实际更改,而我希望所有视图在进行更改时都显示更改,而无需与视图交互以便更新。
有什么想法吗?谢谢,
值得一提的是,我不使用默认的Qt::EditRole 角色来编辑数据,而是使用自定义枚举值(名为ActiveRole)。
这就是我想要的:我的数据模型包含有关如何显示数据的属性,用于生成提供给 viewS 的样式表。
因此,在更改模型时,对于每个视图,它的所有项目都会受到影响,这就是为什么 dataChanged() 信号被发送,索引覆盖所有单元格。
我也尝试发出layoutChanged(),但它似乎并没有改变我的行为。
这里是setData()方法的摘录:
bool DataModel::setData(QModelIndex const& idx, QVariant const& value, int role)
{
if (ActiveRole == role)
{
// Update data...
QModelIndex topLeft = index(0, 0);
QModelIndex bottomRight = index(rowCount() - 1, columnCount() - 1);
emit dataChanged(topLeft, bottomRight);
emit layoutChanged();
return true;
}
return false;
}
这是data() 方法的示例:
QVariant DataModel::data(QModelIndex const& idx, int role) const
{
if (ActiveRole == role)
{
boost::uuids::uuid id;
return qVariantFromValue(id);
}
return QVariant();
}
而flags() 确实表示可编辑模型:
Qt::ItemFlags DataModel::flags(QModelIndex const& idx) const
{
if (false == idx.isValid())
{
return Qt::ItemIsEditable;
}
return QAbstractTableModel::flags(idx) | Qt::ItemIsEditable;
}
我有一个自定义委托,它严重依赖 SO thread 来覆盖 paint 和 sizeHint 方法以绘制 QTextDocument。另外,它把ActiveRole的内容提供给setEditorData中的编辑器,并在setModelData中调用DataMode::setData:
void DataModelDelegate::setEditorData(QWidget* editor, QModelIndex const& idx) const
{
auto active = qVariantValue<boost::uuids::uuid>(idx.data(ActiveRole));
static_cast<DataModelEditor*>(editor)->setActive(active);
}
void DataModelDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, QModelIndex const& idx) const
{
auto active = static_cast<DataModelEditor*>(editor)->getActive();
model->setData(idx, qVariantFromValue(active), ActiveRole);
}
在createEditor() 中,我将来自编辑器的信号插入到我的委托的插槽以提交数据:
QWidget* DataModelDelegate::createEditor(QWidget* parent, QStyleOptionViewItem const& option, QModelIndex const& idx) const
{
auto editor = new DataModelEditor(parent);
connect(editor, SIGNAL(activeItem()), this, SLOT(commitEditorData()));
return editor;
}
当点击一个项目时,编辑器触发activeItem信号;连接的插槽commitEditorData 反过来引发commitData 信号,编辑器在参数中。
所以我的所有视图都使用这些自定义委托、编辑器和数据模型。我正在与之交互的视图确实会立即显示更改,但其他视图也需要将鼠标悬停在它们上方才能显示更改。
【问题讨论】:
-
你能显示
setData()函数的代码吗? -
因此您的 setData 可用于自定义 ActiveRole 而不是标准 EditRole/DisplayRole,但是您为这些项目设置了什么角色?你是否也覆盖
data()?你的视图有自定义渲染委托吗? -
我用一些数据实现、setData、createEditor 等更新了我的问题。希望这会有所帮助!
标签: c++ qt model-view-controller