Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt GUI _ Работа с QModelIndex/QModelIndexList

Автор: AD 10.11.2008, 12:49

Хочется узнать, как правильно работать с индексами модели (QModelIndex/QModelIndexList). Просьба научить некоторым вещам.
Например, есть таблица DeviceList, имеющая следующую структуру: serialNumber char( 8 ), secretKey char( 8 ), security bit, modelID int. Есть желание, чтобы при выделении нескольких элементов, можно было делать следующее:


  1. Узнавать правильное количество выделенных элементов. Я так и не понял, какая функция в QModelIndexList это позволяет. size(), count() - что-то не то показывают, или я не так с ними работаю. :unsure:

  2. Выводить значение serialNumber. Значение остальных столбцов меня не волнует

  3. Правильно обращаться к нужным значениям.

Сможете помочь? Заранее спасибо.

Автор: AD 10.11.2008, 14:03

Еще хотел спросить:

void LicenceBuilder::calcLeftCount(const QItemSelection& selected, const QItemSelection& deselected)
{
    foreach(QItemSelectionRange item, selected)
        selLeft.append(item);
    foreach(QItemSelectionRange item, deselected)
        selLeft.removeAll(item);
}

selLeft имеет тип QItemSelection.
Такой код имеет право на существование? Первоначально, selLeft - пустая выборка.
calcLeftCount - слот, в который попадаем, когда делаем выделение элементов. Можно ведь использовать QItemSelection и QItemSelectionRange вместо QModelIndexList? Я правильный код написал? Так можно выбирать элементы?

Автор: AD 11.11.2008, 17:50

Проблему решил! :) Вот код решения:

source
/* /// Ранее сделано следующее
modelLSNTable = new QSqlTableModel(this);
modelLSNTable -> setTable("DeviceList");
modelLSNTable -> select();


listDBNumbers -> setModel(modelLSNTable);
listDBNumbers -> setSelectionBehavior(QAbstractItemView::SelectRows);
listDBNumbers -> setModelColumn(0);

modelRSNTable = new QSqlTableModel(this);
modelRSNTable -> setTable("DeviceList");

listResultNumbers -> setSelectionBehavior(QAbstractItemView::SelectRows);
listResultNumbers -> setModelColumn(0);
listResultNumbers -> setModel(modelRSNTable);
*/

/// Добавление серийного номера в список номеров для генерации лицензии
void LicenceBuilder::clickAddNumber()
{
    QModelIndexList indexList = selLeft.indexes();
    QString filter("");
    foreach(QModelIndex index, indexList)
    {
        QSqlRecord record = modelLSNTable -> record(index.row());
        QString serialNumber = record.value("serialNumber").toString();
        if(!selectedSerialNumbers.contains(serialNumber, Qt::CaseInsensitive))
            selectedSerialNumbers.append(serialNumber);
    }
    foreach(QString name, selectedSerialNumbers)
    {
        filter += QString("serialNumber = '%1'").arg(name);
        if(name != selectedSerialNumbers.last())
            filter += " or ";
    }

    modelRSNTable -> setFilter(filter);
    modelRSNTable -> select();
    listResultNumbers -> setModel(modelRSNTable);
    connect(listResultNumbers -> selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
        this, SLOT(calcRightCount(const QItemSelection&, const QItemSelection&)));
}

/// Удаление из списка ненужных серийных номеров
void LicenceBuilder::clickDelNumber()
{
    QModelIndexList indexList = selRight.indexes();
    QString filter("");

    foreach(QModelIndex index, indexList)
    {
        QSqlRecord record = modelRSNTable -> record(index.row());
        QString serialNumber = record.value("serialNumber").toString();
        if(selectedSerialNumbers.contains(serialNumber, Qt::CaseInsensitive))
            selectedSerialNumbers.removeAll(serialNumber);
    }
    foreach(QString name, selectedSerialNumbers)
    {
        filter += QString("serialNumber = '%1'").arg(name);
        if(name != selectedSerialNumbers.last())
            filter += " or ";
    }

    if(selectedSerialNumbers.isEmpty())
    {
        if(modelRSNTable) delete modelRSNTable;
        modelRSNTable = new QSqlTableModel(this);
        listResultNumbers -> setModel(modelRSNTable);
        modelRSNTable -> setTable("DeviceList");
    }
    else
    {
        modelRSNTable -> setFilter(filter);
        modelRSNTable -> select();
        listResultNumbers -> setModel(modelRSNTable);
    }
}

/// Вычисление количества выделенных элементов для левого списка
void LicenceBuilder::calcLeftCount(const QItemSelection& selected, const QItemSelection& deselected)
{
    foreach(QItemSelectionRange item, selected)
        selLeft.append(item);
    foreach(QItemSelectionRange item, deselected)
        selLeft.removeAll(item);
}

/// Вычисление количества выделенных элементов для правого списка
void LicenceBuilder::calcRightCount(const QItemSelection& selected, const QItemSelection& deselected)
{
    foreach(QItemSelectionRange item, selected)
        selRight.append(item);
    foreach(QItemSelectionRange item, deselected)
        selRight.removeAll(item);
}


clickAddNumber - слот добавления выделенных элементов из левого QListView в правый QListView
clickDelNumber - слот удаления выделенных элементов из правого QListView
calcLeftCount, calcRightCount - слоты выделения элементов в левом и в правом QListView
selRight, calcLeftCount - имеют тип QItemSelection
selectedSerialNumbers - тип QStringList
modelRSNTable, modelLSNTable - тип QSqlTableModel
listResultNumbers - правый QListView
listDBNumbers - левый QListView

Суть работы слота clickAddNumber:
  1. Просматриваем список индексов, каждое неповторяющееся значение, выбранное из БД, запоминаем в списке строк.
  2. Затем просматриваем полученный список строк и формируем строку фильтра (конструкция WHERE в SQL).
  3. Выполняем выборку из таблицы с обозначенным фильтром.

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)