我已经创建了一个类似Mixin的代理模型(QT5),该模型仅在另一行添加了另一个代理模型,以将QToolBar
添加到表视图的每一行(用于例如,"删除"按钮)。该模型只提供了为第一列填充QList<QVariant>
的方法。代表必须知道每个QVariant
的含义是什么(通常是int
S/enum
S识别动作),并相应地填充QToolBar
。作为最后一个功能,如果没有操作,则不会添加额外的列(在这种情况下,它的行为就像QIdentityProxyModel
)。一旦添加,就无法删除操作。这是另一天的功能。
今天的问题是,当我插入动作(在将模型设置为视图之前执行的操作)时,小区都是空白的。因此,我在信号或知道什么方面做错了什么(我认为在摘要结束时,错误是在add_action
函数中):
template<class proxy_model>
class action_model : public proxy_model
{
QList<QVariant> l_actions;
public:
using base_t = proxy_model;
using base_t::base_t; // Inheriting constructors.
QModelIndex mapFromSource(const QModelIndex& source_idx) const override
{
if (!l_actions.empty() and source_idx.isValid())
return this->createIndex(source_idx.row(),
source_idx.column() + 1);
else // identity proxy case
return base_t::mapFromSource(source_idx);
} // same for mapToSource but with - 1 instead of + 1.
int columnCount(const QModelIndex& parent = QModelIndex()) const override
{ return this->base_t::columnCount() + !l_actions.empty(); }
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
{
if (!l_actions.empty()) {
if (orientation == Qt::Horizontal and section == 0
and role == Qt::DisplayRole)
return "Actions"; // Testing.
else
return base_t::headerData(section - 1, orientation, role);
} else // identity proxy case
return base_t::headerData(section, orientation, role);
}
QVariant data(const QModelIndex& idx, int role) const override
{
if (!l_actions.empty()) {
if (idx.column() == 0 and role = Qt::DisplayRole)
return l_actions; // All the actions for drawing.
else
return QVariant();
} else // identity proxy case
return base_t::data(idx, role);
}
Qt::ItemFlags flags(QModelIndex const& idx) const
{
if (!l_actions.empty() and idx.column() == 0)
return Qt::NoItemFlags; // No editable or selectable
else
return base_t::flags(idx);
}
// And here, I think, is where the fun starts:
// The action could be added before or after the sourceModel
// is set or this model is connected to a view, but I don't
// how that cases are supposed to be managed.
void add_action(QVariant const& action)
{
bool was_empty = l_actions.empty();
l_actions << action;
if (was_empty and !this->insertColumns(0, 1))
throw std::logic_error("Something went wrong");
Q_EMIT this->dataChanged
(this->createIndex(0, 0),
this->createIndex(this->rowCount(), 0),
{ Qt::DisplayRole });
}
};
无需设置操作,该模型可正常运行,包括QAbstractIdentityProxyModel
和QSortFilterProxyModel
作为proxy_model
。但是,设置操作时,视图显示每个单元格,都用QSortFilterProxyModel
和QAbstractIdentityProxyModel
。
这是一个用户地代码:
enum sql_action { DELETE };
auto* table_model = /* My QSqlTableModel */;
auto* view_model = new action_model<QIdentityProxyModel>(my_parent);
auto* table_view = new QTableView;
view_model->add_action(static_cast<int>(sql_action::DELETE));
view_model->setSourceModel(table_model);
table_view->setModel(view_model);
table_view->setSortingEnabled(true);
table_view->setAlternatingRowColors(true);
// The last column is printed in white, not with alternate colors.
table_view->show();
table_model->select();
代表不是问题,因为我没有设置任何人。我希望有一个白色细胞的第一列,但我得到了一个完全白色的桌子。列名显示正常,除了最后一个名称,它仅将0
打印为列名。
我在做什么错?
问题在您的data()
方法中。
- 您不将
role
与Qt::DisplayRole
进行比较,您分配给角色 - 如果您有操作,则返回操作条目或
QVariant()
,从来没有任何数据