Я использую QTableView для отображения некоторых данных внутри таблицы. Поскольку вертикальный заголовок не указан, Qt автоматически присваивает строке идентификатор. В приведенном ниже примере показана следующая таблица:

id|data
-------
1 | B
2 | A
3 | D
4 | C

После сортировки таблицы по столбцу «data»:

id|data
-------
2 | A
1 | B
4 | C
3 | D

Когда пользователь дважды щелкает запись, я хочу иметь возможность идентифицировать кликнувшую строку по ее идентификатору (то есть A = 2, B = 1, C = 4, D = 3). К сожалению, методы, используемые в «onDoubleClicked», возвращают только «новый» идентификатор строки (т. Е. A = 1, B = 2, C = 3, D = 4).

Итак, как мне получить правильный идентификатор строки, когда пользователь дважды щелкает строку?

Table.h

#ifndef TABLE_H
#define TABLE_H

#include <QTableView>
#include <QModelIndex>
#include <QHeaderView>
#include <QDebug>

class Table : public QTableView {
    Q_OBJECT

public:
    explicit Table() : QTableView() {
        setSortingEnabled(true);
        connect(this, &Table::doubleClicked, this, &Table::onDoubleClicked);
    }

public slots:
    void onDoubleClicked(QModelIndex index) {
        qDebug() << index.row();
        qDebug() << verticalHeader()->logicalIndex(index.row());
        qDebug() << verticalHeader()->logicalIndexAt(index.row());
        qDebug() << verticalHeader()->visualIndex(index.row());
        qDebug() << verticalHeader()->visualIndexAt(index.row());
    }
};

#endif // TABLE_H

Main.cpp

#include <QApplication>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>

#include "table.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Table table;
    QStandardItemModel model;

    QList<QStandardItem*> items;
    items.append(new QStandardItem("B"));
    items.append(new QStandardItem("A"));
    items.append(new QStandardItem("D"));
    items.append(new QStandardItem("C"));
    model.appendColumn(items);

    QSortFilterProxyModel proxy;
    proxy.setSourceModel(&model);
    proxy.sort(0, Qt::AscendingOrder);

    table.setModel(&proxy);
    table.show();

    return a.exec();
}
0
Jonas Möller 8 Май 2017 в 10:32

3 ответа

Лучший ответ

У модели нет новой строки (), вы забыли, что передаете их через прокси-модель. Прокси-модель содержит строки () и столбцы (), отличные от исходной модели, поскольку она может переставлять или фильтровать поля.

Исправить несложно - вам просто нужно сопоставить индекс из прокси-модели с исходной.

void onDoubleClicked(QModelIndex index) {
    QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel*>(model()); 

    auto sourceIdx =  m->mapToSource(index);
    qDebug() << sourceIdx.row();
    qDebug() << verticalHeader()->logicalIndex(sourceIdx.row());
    qDebug() << verticalHeader()->logicalIndexAt(sourceIdx.row());
    qDebug() << verticalHeader()->visualIndex(sourceIdx.row());
    qDebug() << verticalHeader()->visualIndexAt(sourceIdx.row());
}
1
Tomaz Canabrava 8 Май 2017 в 09:46

Это работает для меня.

void DeviceData::doubleClicked(QModelIndex cell)
{
    cell.column();
    cell.row();
}

Который вы можете затем вставить в свою модель: model.at(cell.row()).
Или вы создаете функцию find().

-1
Jeroen3 8 Май 2017 в 09:07

Если значение связывается с A, вы можете использовать метод setData, предоставленный QTableWidgetItem. установите значение и получите его обратно с помощью специального флага

< Сильный > EDIT :

Основываться на вашем коде.

items.append(new QStandardItem("B")); тогда вы можете получить QStandardItem make item.setData(1,Qt::UserRole), а 1 - это значение, которое привязывается к "B". Позже вы можете получить значение связывания из item.data(Qt::UserRole). Примечание: он вернет вариант, тогда вам нужно передать его toInt

-1
Shihe Zhang 9 Май 2017 в 02:32