Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Активный поиск в tablewidget


Автор: Belirafor 12.8.2011, 12:08
Привет, всем, участникам форума. Пишу курсовую работу. Вот возникла такая необходимость, как "активный поиск". Суть такова. При вводе строки в поле lEdt_Find в tblWgt_Employee отбирались данные, которые соответствуют этой строке без нажатия кнопки "Поиск". 

Подскажите, пожалуйста как правильно, используя QSortFilterProxyModel выполнить горячий отбор. Я нашел кучу примеров с QStringListModel. А вот для TableWidget ничего. Заранее спасибо.

Вот код:
Код
 
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
#include "QtSql"
#include "QDebug"
#include "QSortFilterProxyModel"
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    db = QSqlDatabase::addDatabase("QSQLITE");
    QDir::setCurrent(QCoreApplication::applicationDirPath());
    db.setDatabaseName("passes.db");
 
    if(!db.open())
    {
        QMessageBox::critical(parent, QObject::tr("Ошибка"), db.lastError().text());
        exit(0);
    }
 
    setWindowTitle(tr("База данных пропусков"));
 
    fncTblWgtEmployee_Refresh();
 
    connect(ui->lEdt_Find, SIGNAL(textChanged(QString)), SLOT(fncFind()));
    connect(ui->tblWgt_Employee, SIGNAL(doubleClicked(QModelIndex)), SLOT(fncDlgEditEmployee_Show()));
 
}
 
void MainWindow::fncFind()       //Тут поле lEdt_Find. Куда вводится строка поиска
{
    qDebug() << ui->lEdt_Find->text();
//    QSortFilterProxyModel proxymodel;
//    proxymodel.setSourceModel();
//    proxymodel.setFilterKeyColumn(1);
//    proxymodel.setFilterWildcard(ui->lEdt_Find->text());
 
}
 
 
 
void MainWindow::fncTblWgtEmployee_Refresh()          //Тут мы заполняем таблицу TableWidget
{
    QSqlQuery qryEmployee_Show;
    qryEmployee_Show.exec(QString("SELECT pasNumID, lname, fname, ptrnym FROM employee_tbl ORDER BY lname DESC"));
 
    QTableWidgetItem *newItem;
    ui->tblWgt_Employee->setRowCount(0);
    ui->tblWgt_Employee->setSortingEnabled(true);
    while(qryEmployee_Show.next())
    {
        ui->tblWgt_Employee->insertRow(0);
        newItem = new QTableWidgetItem();newItem->setText(qryEmployee_Show.value(0).toString());
        ui->tblWgt_Employee->setItem(0,0, newItem);
        newItem = new QTableWidgetItem();newItem->setText(qryEmployee_Show.value(1).toString());
        ui->tblWgt_Employee->setItem(0,1, newItem);
        newItem = new QTableWidgetItem();newItem->setText(qryEmployee_Show.value(2).toString());
        ui->tblWgt_Employee->setItem(0,2, newItem);
        newItem = new QTableWidgetItem();newItem->setText(qryEmployee_Show.value(3).toString());
        ui->tblWgt_Employee->setItem(0,3, newItem);
        newItem = new QTableWidgetItem();
    }
 
    ui->tblWgt_Employee->resizeColumnsToContents();
    ui->tblWgt_Employee->verticalHeader()->setHidden(true);
    ui->tblWgt_Employee->setAlternatingRowColors(true);
    ui->tblWgt_Employee->horizontalHeader()->setStretchLastSection(true);
 
    int rowCount = ui->tblWgt_Employee->rowCount();
    statusBar()->showMessage(tr ("Количество записей в базе: ") + QString::number(rowCount));
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

Автор: borisbn 12.8.2011, 12:49
Код

void MainWindow::fncTblWgtEmployee_Refresh( const QString & filter = QString() )
{
    QString execString = "SELECT pasNumID, lname, fname, ptrnym FROM employee_tbl ";
    if ( filter.isEmpty() == false )
    {
// не знаю, какое поле нужно фильтровать... взял первое попавшееся - lname
        execString += "WHERE lname LIKE %" + filter + "% ";
// след. строки можно закомментировать, если нужно искать только по одному полю
        execString += "OR fname LIKE %" + filter + "% ";
        execString += "OR ptrnym LIKE %" + filter + "% ";
    }
    execString += "ORDER BY lname DESC";
    qryEmployee_Show.exec( execString );
    ...
}

void MainWindow::fncFind()
{
    fncTblWgtEmployee_Refresh( ui->lEdt_Find->text() );
}

Хотя, гораздо более правильно будет использовать model/view + proxyFilterModel

Автор: Belirafor 12.8.2011, 13:03
Нет, я хочу использовать QSortFilterProxyModel, чтобы не нагружать сервер лишними запросами из БД. Тем более, что fncTblWgtEmployee_Refresh используется для вывода информации в виджет tblwgt_Employee.

Цитата

Код

void MainWindow::fncTblWgtEmployee_Refresh( const QString & filter = QString() )
{
    QString execString = "SELECT pasNumID, lname, fname, ptrnym FROM employee_tbl ";
    if ( filter.isEmpty() == false )
    {
// не знаю, какое поле нужно фильтровать... взял первое попавшееся - lname
        execString += "WHERE lname LIKE %" + filter + "% ";
// след. строки можно закомментировать, если нужно искать только по одному полю
        execString += "OR fname LIKE %" + filter + "% ";
        execString += "OR ptrnym LIKE %" + filter + "% ";
    }
    execString += "ORDER BY lname DESC";
    qryEmployee_Show.exec( execString );
    ...
}
void MainWindow::fncFind()
{
    fncTblWgtEmployee_Refresh( ui->lEdt_Find->text() );
}



Хотя, гораздо более правильно будет использовать model/view + proxyFilterModel

Автор: borisbn 12.8.2011, 13:14
В этом случае тебе нужно использовать не QTableWidget, а QTableView.
Ещё нужно наследоваться от QAbstractTableModel и создать QSortFilterProxyModel.
см. примеры http://doc.qt.nokia.com/latest/itemviews-basicsortfiltermodel.html и http://doc.qt.nokia.com/latest/itemviews-customsortfiltermodel.html

Автор: Belirafor 12.8.2011, 22:53
Получается, что в tableWidget этого никак не проделать?

Цитата

В этом случае тебе нужно использовать не QTableWidget, а QTableView.
Ещё нужно наследоваться от QAbstractTableModel и создать QSortFilterProxyModel.
см. примеры Basic Sort/Filter Model и Custom Sort/Filter Model

Автор: Greeneyed 13.8.2011, 09:15
Для работы с моделью используют QTableView. И это есть добро. Этот виджет избавит тебя от ручного запихивания данных в таблицу. Назначаешь для QSortFilterProxyModel источником свою модель данных, напимер QSqlQueryModel, и поле фильтрации. Для QTableView назначаешь моделью QSortFilterProxyModel . Если тебе надо фильтровать по нескольким полям, то нужно наследоваться от QSortFilterProxyModel и писать свой фильтр или использовать подряд несколько QSortFilterProxyModel. Т.е. QSortFilterProxyModel1 - источник для QSortFilterProxyModel2, QSortFilterProxyModel2 - источник для QSortFilterProxyModel3 и т.д.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)