grig_p
grig_p8. Dezember 2017 01:31

Модели QAbstractItemModel и сортировка

Здравствуйте!
Возник вопрос вот на какую тему.
Делаю я табличную модель. Наследовался от QAbstractItemModel.
Модель выглядит следующим образом:

// Строка в модели
struct InfoJournalRec
{
int id;
QDateTime created;
QString sourcer;
QString module;
QString msgType;
int priority;
QString detail;
explicit InfoJournalRec() {}
explicit InfoJournalRec(std::tuple<int, QDateTime, QString, QString, QString, int, QString> params)
: id(std::get<0>(params))
, created(std::get<1>(params))
, sourcer(std::get<2>(params))
, module(std::get<3>(params))
, msgType(std::get<4>(params))
, priority(std::get<5>(params))
, detail(std::get<6>(params))
{}
};
Q_DECLARE_METATYPE(InfoJournalRec)

// Список строк typedef QList<InfoJournalRec> QListInfoJournalRec;
typedef QSharedPointer<QListInfoJournalRec> InfoJournalRecListPtr;
Q_DECLARE_METATYPE(InfoJournalRecListPtr) // Сама модель class TableJournalModel : public QAbstractItemModel { Q_OBJECT public: explicit TableJournalModel(QObject *parent = Q_NULLPTR); int rowCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; Qt::ItemFlags flags(const QModelIndex &index) const; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &child) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; public slots: void load(); private: InfoJournalRecListPtr m_records = Q_NULLPTR; };

В ней имеется защищенный указатель на список список QList с данными и перекрыт ряд методов, обеспечивающих доступ к ним.
Реализация метода доступа к данным выглядит следующим образом:
QVariant TableJournalModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || (m_records == Q_NULLPTR))
        return QVariant();

    if ((index.row() < 0) || (index.row() >= m_records->count()))
        return QVariant();

    if (role == Qt::DisplayRole || role == Qt::EditRole)
    {
        int n = 0;
        auto di = m_records->begin();
        while (di != m_records->end())
        {
            InfoJournalRec ijr = *di;
            if (n == index.row())
            {
                if (index.column() == 0)
                    return ijr.id;
                else
                if (index.column() == 1)
                    return ijr.created;
                else
                if (index.column() == 2)
                    return ijr.sourcer;
                else
                if (index.column() == 3)
                    return ijr.module;
                else
                if (index.column() == 4)
                    return ijr.msgType;
                else
                if (index.column() == 5)
                    return priorityTitles.value(ijr.priority);
                else
                if (index.column() == 6)
                    return ijr.detail;
            }
            ++n;
            ++di;
        }
        // Если мы не вернули ничего, то вернем пустое значение
        return QVariant();
    }
    else
        return QVariant();
}
Подключение модели осуществляется с помощью QSortFilterProxyModel следующим образом:
    m_model = new TableJournalModel();
m_proxyModel->setSourceModel(m_model); ui->TableView->setModel(m_proxyModel);
Таблица должна:
1. Сортироваться по любому столбцу.
2. Последний столбец detail не должен выводиться в таблице, ибо большой по размеру, а его значение должно выводиться в отдельном поле при выборе строки таблицы.
TableView допускает сортировку. Кроме того, реализована обработка клика на столбце:
    connect(ui->TableView->horizontalHeader(), &QHeaderView::sectionClicked, this, [=](int logicalIndex)// Выделение и активация строки модели
void TableTailPbxLog::onItemActivated(QModelIndex index)
{
    QModelIndex idxDetail = m_model->index(index.row(), 6);
    QString st = m_model->data(idxDetail, Qt::DisplayRole).toString();
    ui->teDetail->setText(st);
}
    {
        ui->TableView->sortByColumn(logicalIndex);
    });
Сортировка работает превосходно.

Выделение и отображение данных из столбца также работает:
// Выделение и активация строки модели
void TableTailPbxLog::onItemActivated(QModelIndex index)
{
    QModelIndex idxDetail = model->index(index.row(), 6);
    QString st = model->data(idxDetail, Qt::DisplayRole).toString();
    ui->teDetail->setText(st);
}
Но, если отсортировать таблицу не в последовательности заполнения, то данные берутся не из тех строк, которые выделены, а из строки, номер которой выбран в отсортированной таблице.
То есть, в процедуре onItemActivated параметр index заполнен данными по отсортированной модели
index.data()->toString(... выводит правильное отображение, а
index.row() содержит номер строки в отсортированной модели, и я не знаю, как получить индексы записей столбцов этой строки, ибо мне нужны индексы строк в исходной модели.

Вопрос, как правильно получить индекс строки в исходной модели?
Не хотелось бы переходить к QStandarditemModel, ибо там много накладных расходов.
Заранее благодарен за ответ.


Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

3
Evgenii Legotckoi
  • 8. Dezember 2017 03:10
  • (bearbeitet)

День добрый!
Вы же используете модель QSortFilterProxyModel для сортировки. А она имеет метод mapToSource, которые будет возвращать индекс исходной модели данных, если в него передать индекс прокси модели. Фактическив в TableView  у вас находится прокси модель, которая мапится на исходную. Ваша строка не соответствует ожидаемому результату потому, что Вы имеете индекс прокси модели. Вам нужно всего лишь преобразовать его в индес исходной модели.

const QModelIndex& sourceIndex = m_proxyModel->mapToSource(proxyIndex);

И если интересно, могу высказать мнение по поводу качества кода в целом. У вас есть ряд огрехов, которые имеет смысл исправить. Это касается код стайла, использования устаревшего подхода, и несколько избыточного и менее читаемого использования некоторых синтаксических конструкций языка.
    grig_p
    • 8. Dezember 2017 03:35

    Спасибо!
    Все получилось.
    Неужели все так просто. Вот уж точно "Век живи - век учись"

      Evgenii Legotckoi
      • 8. Dezember 2017 03:36

      я бы по-другому сказал )) "Документация - наш друг"

        Kommentare

        Nur autorisierte Benutzer können Kommentare posten.
        Bitte Anmelden oder Registrieren
        Letzte Kommentare
        A
        ALO1ZE19. Oktober 2024 15:19
        Fb3-Dateileser auf Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
        ИМ
        Игорь Максимов5. Oktober 2024 14:51
        Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
        d
        dblas55. Juli 2024 18:02
        QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
        k
        kmssr9. Februar 2024 02:43
        Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
        Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
        Jetzt im Forum diskutieren
        J
        JacobFib17. Oktober 2024 10:27
        добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
        JW
        Jhon Wick1. Oktober 2024 22:52
        Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
        КГ
        Кирилл Гусарев27. September 2024 16:09
        Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
        F
        Fynjy22. Juli 2024 11:15
        при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

        Folgen Sie uns in sozialen Netzwerken