How to filter QTableModel by rows?

I have a main data model and 2 tables, each of which uses a proxy model. In this model, there is one important point m_check_box_states. I put a checkbox in the 0th column, by clicking on which I essentially select the entire row

#include <QAbstractTableModel>


class EditableTableModel : public QAbstractTableModel {

    public:
        EditableTableModel(QObject *parent = nullptr);
    
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    
        int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    
        QVariant data(const QModelIndex &index, 
                      int role = Qt::DisplayRole) const override;
    
        bool setData(const QModelIndex &index, const QVariant &value, 
                     int role = Qt::EditRole) override;
    
        Qt::ItemFlags flags(const QModelIndex &index) const override;

        void addEntry(const std::vector<QString> &newEntry);
        
        void beginInsertion(int size);

        void endInsertion();

        QVariant headerData(int section, Qt::Orientation orientation, 
                            int role = Qt::DisplayRole) const override;
        
        void setHeaders(const QStringList& headers);
    
    private:
        std::vector<std::vector<QString>> m_data;
        std::vector<bool> m_check_box_states;
        QStringList m_headers;
};
EditableTableModel::EditableTableModel(QObject *parent) : QAbstractTableModel(parent),
                                                                    m_check_box_states(std::vector<bool>(rowCount(), false))
{

}

int EditableTableModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_data.size();
}

QVariant EditableTableModel::data(const QModelIndex &index, int role) const 
{
    const bool isInvalidIndex = !index.isValid() || 
                                 index.row() >= rowCount() ||
                                 index.column() >= columnCount();
    
    if (isInvalidIndex)
        return QVariant();
    if (role == Qt::CheckStateRole && index.column() == 0)
    {
        return m_check_box_states.at(index.row()) ? Qt::Checked : Qt::Unchecked;
    }
    
    if (role == Qt::DisplayRole) 
    {
        return m_data.at(index.row()).at(index.column());
    }


    return QVariant();
}

bool EditableTableModel::setData(const QModelIndex &index, const QVariant &value, int role) 
{
    const bool isInvalidIndex = !index.isValid() || 
                                 index.row() >= rowCount() ||
                                 index.column() >= columnCount();

    if (isInvalidIndex)
        return false;

    if (role == Qt::EditRole) 
    {
        m_data.at(index.row()).at(index.column()) = value.toString();
        emit dataChanged(index, index, {role});
        return true;

    } 
    else if (role == Qt::CheckStateRole && index.column() == 0) 
    {
        m_check_box_states.at(index.row()) = value.toBool();
        emit dataChanged(index, index, {role});
        return true;
    }

    return false;
}

Qt::ItemFlags EditableTableModel::flags(const QModelIndex &index) const 
{
    Qt::ItemFlags flags = QAbstractTableModel::flags(index);

    if (!index.isValid())
        return Qt::NoItemFlags;
    
    if (index.column() == 0) {
        flags |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
    } else {
        flags |= Qt::ItemIsEditable;
    }
    return flags;
}

void EditableTableModel::addEntry(const std::vector<QString> &newEntry) 
{ 
    Q_ASSERT(newEntry.size() == (size_t)columnCount());
    m_check_box_states.emplace_back(false); 
    m_data.emplace_back(newEntry);
}

int EditableTableModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_headers.size(); 
}

void EditableTableModel::beginInsertion(int size)
{    
    int start_index = m_data.size();
    int new_size    = start_index + size;
    int end_index   = new_size - 1;
    
    beginInsertRows(QModelIndex(), start_index, end_index);
    
    m_data.reserve(m_data.size() + size);
    m_check_box_states.reserve(m_data.size() + size);
}

void EditableTableModel::endInsertion()
{
    endInsertRows();
}

void EditableTableModel::setHeaders(const QStringList &headers) 
{

    m_headers = headers;
    emit headerDataChanged(Qt::Horizontal, 0, m_headers.size() - 1);
}

QVariant EditableTableModel::headerData(int section, Qt::Orientation orientation, int role) const 
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
        return m_headers.at(section);
    }
    return QVariant();
}

My 2 proxy models.
The first ColumnFilterProxyModel displays specific columns that I specify as an array. My model has 8 columns and I display 3 columns in one table and the remaining 5 in the other, but not at once!

#include <QSortFilterProxyModel>
#pragma once

class ColumnFilterProxyModel : public QSortFilterProxyModel {
public:

    ColumnFilterProxyModel(const QList<int> &columns, QObject *parent = nullptr);

    int rowCount(const QModelIndex &parent = QModelIndex()) const override;

    int columnCount(const QModelIndex &parent = QModelIndex()) const override;

    QVariant data(const QModelIndex &index, int role) const override;
    
    bool setData(const QModelIndex &index, const QVariant &value, 
                 int role = Qt::EditRole) override;
    

protected:
    QModelIndex mapToSource(const QModelIndex &proxyIndex) const override;
    QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override;

private:
    QList<int> m_columns_nums;
};


#include "columnfilterproxymodel.h"
#include <iostream>

ColumnFilterProxyModel::ColumnFilterProxyModel(const QList<int> &columns, 
                                               QObject *parent) : 
                                               QSortFilterProxyModel(parent), 
                                               m_columns_nums(columns) {}

int ColumnFilterProxyModel::rowCount(const QModelIndex &parent) const  
{
    return parent.isValid() ? 0 : sourceModel()->rowCount();
}

int ColumnFilterProxyModel::columnCount(const QModelIndex &parent) const 
{
    return parent.isValid() ? 0 : m_columns_nums.size();
}

QVariant ColumnFilterProxyModel::data(const QModelIndex &index, int role) const 
{
    const bool isInvalidIndex = !index.isValid() || 
                                 index.row() >= sourceModel()->rowCount() ||
                                 index.column() >= columnCount();

    if (isInvalidIndex || (role != Qt::DisplayRole && 
                           role != Qt::EditRole && 
                           role != Qt::CheckStateRole))
        return QVariant();


    QModelIndex sourceIndex = this->mapToSource(createIndex(index.row(), index.column()));
    
    return sourceModel()->data(sourceIndex, role);
}
    
bool ColumnFilterProxyModel::setData(const QModelIndex &index, 
                                     const QVariant &value, 
                                     int role) 
{
    QModelIndex sourceIndex = mapToSource(this->index(index.row(), m_columns_nums.at(index.column())));
    return sourceModel()->setData(sourceIndex, value, role);
}
    
QModelIndex ColumnFilterProxyModel::mapToSource(const QModelIndex &proxyIndex) const 
{
    const bool isInvalidIndex = !proxyIndex.isValid() || 
                                 proxyIndex.row() >= sourceModel()->rowCount() || 
                                 proxyIndex.column() >= columnCount();
    if(isInvalidIndex)
        return QModelIndex();
    return sourceModel()->index(proxyIndex.row(), m_columns_nums.at(proxyIndex.column()));
}

QModelIndex ColumnFilterProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
{

    const bool isInvalidIndex = !sourceIndex.isValid() || 
                               sourceIndex.row() >= rowCount() || 
                               sourceIndex.column() >= columnCount();
    
    if (isInvalidIndex)
        return QModelIndex();

    int proxyColumn = m_columns_nums.at(sourceIndex.column());
    
    return createIndex(sourceIndex.row(), proxyColumn);
}

#include "columnfilterproxymodel.h"

class CheckableFilterProxyModel : public ColumnFilterProxyModel {

public:
    CheckableFilterProxyModel(const QList<int> &columns, 
                              QObject *parent = nullptr);
    QVariant data(const QModelIndex &index, int role) const override;

protected:
    bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
    
    QModelIndex mapToSource(const QModelIndex &proxyIndex) const override;
    QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override;
};

In this proxy model I want to display the 5 remaining columns, but only those rows that were selected using the checkbox. The 5 columns are displayed correctly, but I can’t really figure out how to filter the rows. The problem is most likely here and most likely with the indexes.

#include "checkablefilterproxymodel.h"
#include <iostream>


bool CheckableFilterProxyModel::filterAcceptsRow(int sourceRow, 
                                                 const QModelIndex &sourceParent) const
{
    QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
    return ColumnFilterProxyModel::data(index, Qt::CheckStateRole).toBool();
}


QModelIndex CheckableFilterProxyModel::mapToSource(const QModelIndex &proxyIndex) const
{

    return ColumnFilterProxyModel::mapToSource(proxyIndex);
}

QModelIndex CheckableFilterProxyModel::mapFromSource(const QModelIndex &proxyIndex) const
{
    std::cout << proxyIndex.row() << " " << proxyIndex.column() << std::endl;
    return QModelIndex();
}


QVariant CheckableFilterProxyModel::data(const QModelIndex &index, int role) const
{
    
    return ColumnFilterProxyModel::data(index, role);
}

CheckableFilterProxyModel::CheckableFilterProxyModel(const QList<int> &columns, 
                              QObject *parent) : ColumnFilterProxyModel(columns, parent) 
{

}

I need to make it so that the rows selected by the checkbox in one table are displayed in another.
This is how I initialize the columns and the QTableView where it all is displayed

    main_model = new EditableTableModel();
    main_model->setHeaders({
                            "Model Name", 
                            "Color1", 
                            "Color2", 
                            "Picture",
                            "Line Style",
                            "Fill Style", 
                            "Model Name2", 
                            "Model Name3"});

    QList<int> columns1 = {0, 1, 2, 3, 4, 5};
    CheckableFilterProxyModel *proxyModel1 = new CheckableFilterProxyModel(columns1);
    proxyModel1->setSourceModel(main_model);
    editor_tableView->setModel(proxyModel1);
    editor_tableView->setShowGrid(false);

    
    QList<int> columns3 = {0, 6, 7};
    ColumnFilterProxyModel *proxyModel3 = new ColumnFilterProxyModel(columns3);
    proxyModel3->setSourceModel(main_model);
    proxyModel3_tableView->setModel(proxyModel3);

Here is an example of the data I have in the model:

{"instance", "red", "red", "none", "none", "solid", "instance", "label"}
{"instance", "blue", "blue", "none", "none", "solid", "instance", "drawing"}
{"_gdsii__", "green", "none", "none", "none", "solid", "instance3", "instance3" }

Accordingly, I have 3 rows. Having selected the 3rd row in one table, in the second I see the row under index 0, although I expect to see the row under index 3, all attention is on name

Here is the selection in one table

This is what is added to the other one

Actually, there is an error in the indexes and it is probably here

QModelIndex CheckableFilterProxyModel::mapToSource(const QModelIndex &proxyIndex) const
{

    return ColumnFilterProxyModel::mapToSource(proxyIndex);
}

But it is not clear to me how I can recalculate the index for all selected elements at this stage and display them correctly.

P.S:
What I tried was saving the sourceRow in the QSet in the filterAcceptsRow function, but this approach seems hacky to me, because filterAcceptsRow is a constant method. Also, adding a getter to get std::vector m_check_box_states and already having this vector in my proxy model to calculate the index seems to be also not a very pleasant solution, because for each selection I will have to run through all the elements of this vector, and I will have to take into account a lot of things. Actually, it seems to me that I do not understand well how all these proxy models work in QT, and that is why my solutions, in my own opinion, are idiotic

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật