专门用于添加列的 QAbstractProxyModel:表格单元格变为空

Posted

技术标签:

【中文标题】专门用于添加列的 QAbstractProxyModel:表格单元格变为空【英文标题】:Specializing a QAbstractProxyModel for adding a column: the table cells becomes empty 【发布时间】:2016-12-06 03:16:35 【问题描述】:

我创建了一个类似 mixin 的代理模型 (Qt5),它只是向另一个代理模型添加了额外的第一列,用于向表视图的每一行添加 QToolBar 操作(例如,“删除”按钮)。该模型只是提供了一种为第一列填充QList<QVariant> 的方法。代表必须知道每个QVariant 的含义(通常是ints/enums 标识操作),并相应地填充QToolBar。作为最后一个功能,如果没有操作,则不会添加额外的列(在这种情况下,它的行为类似于 QIdentityProxyModel)。添加后,操作将无法删除。这是另一天的功能。

今天的问题是,当我插入动作(我在将模型设置为视图之前这样做)时,单元格都是空白的。所以,我在信号上做错了什么,或者谁知道是什么(我认为错误出在add_action 函数中,在 sn-p 的末尾):

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 );
    

;

如果不设置操作,模型可以正常工作,QAbstractIdentityProxyModelQSortFilterProxyModel 都为 proxy_model。但是,在设置操作时,视图会将每个单元格显示为空白,QSortFilterProxyModelQAbstractIdentityProxyModel

这是一个用户登陆代码:

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 作为列名。

我做错了什么?

【问题讨论】:

可能是缺少mapToSource()columnCount() 中的代码也不理想,您依赖 true 为 1 而不是任何其他非零值 mapToSource 被评论为缩短了问题,就在mapFromSource 的下方(因为它们实际上是相同的)。出于同样的原因,columnCount 被缩短了。在我的代码中,我使用 if 而不进行转换。不管怎样,emtpy 返回一个bool,标准确保false 布尔值转换为0int1 转换为true。所以,我认为代码是正确的、符合标准的等等。无论如何,问题一定出在其他地方。 嗯,当然,我只是觉得将布尔值添加到整数很奇怪。 我也有类似的问题,你最终成功了吗? @brembo 我解决了它,但我不记得如何解决了。我想我在下面的 KevinKrammer 答案的建议下解决了它,但是如果我没有将他的解决方案标记为答案,是因为我错过了一些更复杂的东西,这取决于我的代码的其他内容,或者也许我尝试了很多想法,但我不确定我是如何解决它的。 【参考方案1】:

问题出在您的data() 方法中。

    您不会将 role 与您分配给角色的 Qt::DisplayRole 进行比较 如果您有操作,则要么返回操作条目,要么返回 QVariant(),绝不返回任何数据

【讨论】:

以上是关于专门用于添加列的 QAbstractProxyModel:表格单元格变为空的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能简单地添加一个包含所有列的索引?

spark中用于添加新列的withcolumn()未显示结果[重复]

sql 用于将列更改为作为主键的标识列的SQL代码。您必须删除密钥,删除列,将列添加回i

将一列的值用于另一列(SQL Server)?

Sencha EXT JS datagrid滚动条专门在列上?

添加对不同于 id 的所选列的引用