Как отобразить отфильтрованные данные QSqlTableModel в другом TableView в Qt?

#qt #filter #tableview #show #qsqltablemodel

#qt #Фильтр #просмотр таблицы #показать #qsqltablemodel

Вопрос:

Я загрузил базу данных с помощью QSqlTableModel и показываю ее в tableView1 . Теперь я настроил фильтр для этого QSqlTableModel и хочу показать отфильтрованные данные в tableView2 . tableView1 и tableView2 не должны взаимодействовать друг с другом. Тогда, как это показать, и какой самый быстрый способ?

Примечание:

  1. База данных содержит только число без строки, а размер невелик (около 500 * 5);
  2. Данные в tableView2 не нужно сохранять.

Основной код выглядит следующим образом:

 QSqlTableModel *model = new QSqlTableModel(NULL, db);
model->setTable(tableName);
model->select();
tableView->setModel(model);
tableView->show();
model->setFilter("colum5 > 10");
  

Я не хочу записывать отфильтрованные данные в другую базу данных, а затем сохранять их, показывать. Я хочу найти несколько лучших способов показать это. Или мне нужно извлечь отфильтрованные данные в матрицу и отобразить эту матрицу в tableView ? Кто-нибудь может высказать какие-нибудь соображения? Спасибо

Комментарии:

1. Есть ли какая-либо причина, по которой вы не можете иметь два QSqlTableModel s — по одному для каждого QTableView — но которые оба используют один и тот же QSqlDatabase экземпляр?

2. @G.M. потому что я хочу иметь только одну копию этой базы данных. Если я использую два QSqlTableModel , это пустая трата памяти.

Ответ №1:

Поскольку вы хотите отобразить обе модели, я думаю, что самым чистым способом сделать то, что вы хотите, было бы использовать QSortFilterProxyModel подкласс (я буду называть его model2 ) в tableView2 , переопределить filterAcceptsRow() , чтобы принимать только строки с column5 > 10 , и установить для его исходной модели значение model1 (ваш оригинал QSqlTableModel ).

Это приведет к синхронизации обеих моделей вместе, редактирование любой из них будет автоматически применено к обеим моделям.

Вот как может выглядеть ваш QSortFilterProxyModel подкласс:

 class MyFilterModel : public QSortFilterProxyModel{
public:
    explicit MyFilterModel(QObject* parent= nullptr):QSortFilterProxyModel(parent){}
    ~MyFilterModel(){}

    void setCol5Min(int val){
        col5Min= val;
        invalidateFilter();
    }

protected:
    bool filterAcceptsRow(int source_row, const QModelIndex amp;/*source_parent*/) const{
        //get index using source_row, and the column you want to filter
        QModelIndex index4= sourceModel()->index(source_row, 4);
        //accept the row only when col5's value is greater than col5Min
        return (sourceModel()->data(index4).toInt() > col5Min);
    }
private:
    int col5Min;
};
  

и вы можете использовать это следующим образом:

 QSqlTableModel *model1 = new QSqlTableModel(this, db);
model1->setTable(tableName);
model1->select();
tableView1->setModel(model1);

MyFilterModel* model2= new MyFilterModel(this);
model2->setCol5Min(10);
model2->setSourceModel(amp;model1);
tableView2->setModel(model2);
  

Единственным недостатком вышеупомянутого подхода является то, что фильтрация не выполняется в базе данных (это делается в коде вашего приложения), поэтому вы не можете воспользоваться преимуществами любых индексов, которые у вас могут быть, col5 например (но если у вас 500 строк, это вообще не проблема).

Если вы хотите, чтобы фильтрация выполнялась в базе данных, вам придется использовать два отдельных QSqlTableModel с:

 QSqlTableModel *model1 = new QSqlTableModel(this, db);
model1->setTable(tableName);
model1->select();
tableView1->setModel(model1);

QSqlTableModel *model2 = new QSqlTableModel(this, db);
model2->setTable(tableName);
model2->setFilter("colum5 > 10");
model2->select();
tableView2->setModel(model2);
  

Но это не приведет к синхронизации ваших табличных представлений. Когда пользователь редактирует одно из табличных представлений, вам придется обновить другое.

Комментарии:

1. Большое вам спасибо. QSortFilterProxyModel это хороший способ решения моей проблемы, поскольку мне нужно синхронизировать с представлениями модели. Еще раз спасибо.