2016-10-24 11 views
0

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

Примечание:

  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? Может ли кто-нибудь дать какие-то мысли? Спасибо

+0

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

+0

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

ответ

2

Поскольку вы хотите отобразить обе модели, я думаю, что самый чистый способ сделать то, что вы хотите, будет с помощью QSortFilterProxyModel подкласса (я буду ссылаться на него как model2) в tableView2, переопределения filterAcceptsRow() принимать только те строки, с column5 > 10, и установите его source model на 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 &/*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(&model1); 
tableView2->setModel(model2); 

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

Если вы хотите, фильтрацию, чтобы быть выполнена в базе данных, Вы должны будете использовать два отдельных QSqlTableModel S:

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

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

+0

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

Смежные вопросы