【问题标题】:Retrieving the row number of a QTableView检索 QTableView 的行号
【发布时间】:2017-05-08 07:32:44
【问题描述】:

我正在使用 QTableView 在表格中显示一些数据。因为没有给出垂直标题,所以 Qt 会自动为一行分配一个 row-id。下面的例子显示了下表:

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

根据“数据”列对表格进行排序后:

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

当用户双击一个条目时,我希望能够通过其 id 来识别单击的行(即 A=2、B=1、C=4、D=3)。不幸的是,“onDoubleClicked”中使用的方法只返回“新”行ID(即A=1、B=2、C=3、D=4)。

那么当用户双击一行时,我如何检索正确的行 ID?

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

【问题讨论】:

    标签: c++ qt qtableview


    【解决方案1】:

    模型没有新的 row(),您忘记了您是通过代理模型传递它们的。代理模型拥有与原始模型不同的 rows() 和 columns(),因为它可以重新排列或过滤字段。

    修复很简单 - 您只需将索引从代理模型映射到原始模型。

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

    【讨论】:

    • 那怎么排序呢?
    • 这与 OP 问题无关。
    【解决方案2】:

    这些对我有用。

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

    然后您可以将其输入到您的模型中:model.at(cell.row())
    或者你创建一个find() 函数。

    【讨论】:

      【解决方案3】:

      如果该值与A 绑定,则可以使用QTableWidgetItem 提供的setData 方法。设置该值并通过特定标志取回该值。可能是Qt::UserRole

      编辑:

      基于您的代码。

      items.append(new QStandardItem("B")); 然后你可以得到QStandardItem 使item.setData(1,Qt::UserRole)1 是绑定到"B" 的值。稍后你可以从item.data(Qt::UserRole) 获取绑定值。注意:它会返回一个变体然后你需要转发toInt

      【讨论】:

      • 我不确定,如果我理解正确,你能改写你的答案吗?不幸的是,我无法访问各个项目,因为它们是通过 QSqlQueryModel 添加的。
      • 您可以通过QTableView 获取单个项目。如果不能,我的方法不可用。
      猜你喜欢
      • 2014-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-13
      • 1970-01-01
      • 2012-01-05
      相关资源
      最近更新 更多