我编写了一个自定义数据模型,用几个QTableViews显示。
从技术上讲,一切正常:我的观点显示了我的模型所做的更改。我的数据模型是可编辑的,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
的内容,并在DataMode::setData
中调用setModelData
:
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
信号。
所以我的所有视图都使用这些自定义委托,编辑器和数据模型。我正在与之交互的视图会立即显示更改,但其他视图需要将鼠标悬停在它们上方以显示更改。
答案 0 :(得分:6)
我实际上发现了问题,即我的其他视图没有正确通知数据更改:我的每个视图都显示了我的数据的不同部分,因此其他视图需要通知dataChanged()
,但对于他们自己的,适当的指数。
另外,在我的Qt应用程序不是窗口管理器中的活动窗口时,我也遇到了更新视图的问题。解决方案是在主窗口上调用repaint()
。
答案 1 :(得分:5)
我遇到了同样的问题,请允许我在piwi的答案中添加详细的说明。如果更改数据以及更新单列或多列(或行,具体取决于您的要求)的内容,则应发出一组从左上到右下的索引。例如,如果您有一个如下表:>
,现在您已经更改了一些数据,并且想要更新单元格第1行第1-2列,那么您应该发出信号dataChange
emit datachange(index(1,1),index(1,2));
答案 2 :(得分:0)
您是否在呼叫setData()
? dataChanged()
信号真的发出了吗?将一些调试日志记录槽连接到它。我敢于推测这与你的问题非常类似: