piw*_*iwi 7 c++ model-view-controller qt
我编写了一个自定义数据模型,用几个QTableViews显示.
从技术上讲,一切正常:我的观点显示了我的模型所做的更改.我的数据模型是可编辑的,并且该setData()方法确实发出dataChanged()信号并true在成功编辑时返回.
但是,我的问题是我必须将鼠标移到a 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;
}
Run Code Online (Sandbox Code Playgroud)
以下是该data()方法的示例:
QVariant DataModel::data(QModelIndex const& idx, int role) const
{
if (ActiveRole == role)
{
boost::uuids::uuid id;
return qVariantFromValue(id);
}
return QVariant();
}
Run Code Online (Sandbox Code Playgroud)
并且flags()确实表明了一个可编辑的模型:
Qt::ItemFlags DataModel::flags(QModelIndex const& idx) const
{
if (false == idx.isValid())
{
return Qt::ItemIsEditable;
}
return QAbstractTableModel::flags(idx) | Qt::ItemIsEditable;
}
Run Code Online (Sandbox Code Playgroud)
我有一个自定义委托,它严重依赖于这个SO线程来覆盖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);
}
Run Code Online (Sandbox Code Playgroud)
在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;
}
Run Code Online (Sandbox Code Playgroud)
单击某个项目时,编辑器会触发该activeItem信号; 连接的插槽commitEditorData依次commitData通过参数中的编辑器提升信号.
所以我的所有视图都使用这些自定义委托,编辑器和数据模型.我正在与之交互的视图会立即显示更改,但其他视图需要将鼠标悬停在它们上方以显示更改.
我实际上发现了问题,那就是我的其他视图没有被正确通知数据更改:我的每个视图都显示了我的数据的不同部分,所以其他视图需要被通知dataChanged(),但是对于他们自己的,正确的索引.
另外,在我的Qt应用程序不是窗口管理器中的活动窗口时,我也遇到了更新视图的问题.解决方案是调用repaint()主窗口.
我遇到了同样的问题,请允许我在piwi的答案中添加详细的说明。如果更改数据以及更新单列或多列(或行,具体取决于您的要求)的内容,则应发出一组从左上到右下的索引。例如,如果您有一个如下表:

并且,现在您已经更改了一些数据,并且想要更新单元格第1行第1-2列,那么您应该发出信号dataChange
emit datachange(index(1,1),index(1,2));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27878 次 |
| 最近记录: |