我有问题要正确转置我从db接收到的表。我按照找到here的路径,最后在子类化QAbstractProxyModel中 - 就像描述here一样。 不幸的是,它没有完全发挥作用,这就是问题所在:
我有什么:
X | A | B
----------
1 | A1 | B1
2 | A2 | B2
我想要的是什么:
X | 1 | 2
----------
A | A1 | A2
B | B1 | B2
我得到了什么:
X | 1 | 1
----------
A | A1 | A2
A | B1 | B2
正如您所看到的,数据被正确转换,但标题变得糟糕......我真的需要它们:(
我尝试手动设置标题数据,但也失败了:
origModel = new QSqlQueryModel; // set query and so on
transposedModel = new TransposeProxyModel;
transposedModel->setSourceModel(origModel );
for (int i = 0; i < origModel->columnCount(); i++) {
qDebug() << "origModel->Qt::Horizontal(" << i << ")" << origModel->headerData(i, Qt::Horizontal, Qt::DisplayRole);
//transposedModel->setHeaderData(i, Qt::Vertical, origModel->headerData(i, Qt::Horizontal, Qt::DisplayRole), Qt::DisplayRole); //#try1
transposedModel->setHeaderData(i, Qt::Vertical, QVariant( "abc" ), Qt::DisplayRole); // #try2
}
无论我尝试#1还是#2 - 调用setHeaderData评估为false ......
有什么想法吗?
修复为@ViníciusGobboA. de Oliveira指出
答案 0 :(得分:4)
好吧,如果您使用了链接的示例代码,则应覆盖TransposeProxyModel类的headerData方法的默认定义,如下所示:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const {
return sourceModel()->headerData(section, (orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal), role);
}
忘掉setHeaderData和setData方法:你想要一个依赖原始代理模型的代理模型!
好吧,不知道到底出了什么问题,你正在使用哪个Qt版本?试试这段代码,它在这里完美运行:
#include <QtCore>
#include <QtWidgets>
class TransposeProxyModel: public QAbstractProxyModel {
public:
TransposeProxyModel(QObject *p = 0):
QAbstractProxyModel(p)
{
}
QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const{
return index(sourceIndex.column(), sourceIndex.row());
}
QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const{
return sourceModel()->index(proxyIndex.column(), proxyIndex.row());
}
QModelIndex index(int r, int c, const QModelIndex &ind=QModelIndex()) const{
return createIndex(r,c);
}
QModelIndex parent(const QModelIndex&) const {
return QModelIndex();
}
int rowCount(const QModelIndex &) const{
return sourceModel()->columnCount();
}
int columnCount(const QModelIndex &) const{
return sourceModel()->rowCount();
}
QVariant data(const QModelIndex &ind, int role) const {
return sourceModel()->data(mapToSource(ind), role);
}
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const {
return sourceModel()->headerData(section,
(orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal),
role);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QStandardItemModel model(3,3);
model.setData(model.index(0,0), "1");
model.setData(model.index(0,1), "2");
model.setData(model.index(0,2), "3");
model.setData(model.index(1,0), "4");
model.setData(model.index(1,1), "5");
model.setData(model.index(1,2), "6");
model.setData(model.index(2,0), "7");
model.setData(model.index(2,1), "8");
model.setData(model.index(2,2), "9");
model.setHeaderData(0, Qt::Horizontal, "a");
model.setHeaderData(1, Qt::Horizontal, "b");
model.setHeaderData(2, Qt::Horizontal, "c");
TransposeProxyModel trans;
trans.setSourceModel(&model);
QSplitter split;
QTableView *t1 = new QTableView(&split);
t1->setModel(&model);
QTableView *t2 = new QTableView(&split);
t2->setModel(&trans);
split.show();
return a.exec();
}
大多数代码来自您提供的链接,我刚刚编写了headerData方法。
答案 1 :(得分:0)
有趣的是 - doc表示这是一个虚拟方法:
虚拟QVariant headerData(int section,Qt :: Orientation orientation, int role)const
(...)
QVariant QAbstractProxyModel :: headerData(int section,Qt :: Orientation orientation,int role)const [virtual]
从QAbstractItemModel :: headerData()重新实现。
但实际上缺少virtual
关键字:
C:\ Qt的\ Qt5.2.1 \ 5.2.1 \ msvc2010 \包括\ QtCore \ qabstractproxymodel.h
(...)
QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const; //line76
QVariant headerData(int section, Qt::Orientation orientation, int role) const; //line77
我检查了正常的Qt目录,但它也丢失了:
C:\ Qt的\ Qt5.2.1 \ 5.2.1 \ SRC \ qtbase \ SRC \ corelib的\ itemmodels \ qabstractproxymodel.h
(...)
QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
我做了一个测试:
sim = new QStandardItemModel (3,3);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++ ) {
sim->setData(sim->index(i,j), QString("%1%2").arg(QChar(j+65), QString().setNum(i+1)));
if (i==0)
sim->setHeaderData(j, Qt::Horizontal, QChar(j+65));
}
sim->setHeaderData(i, Qt::Vertical, i+1);
}
transposedModel = new TransposeProxyModel;
transposedModel->setSourceModel(sim);
QAbstractItemModel * aim = transposedModel;
QAbstractProxyModel *apm = transposedModel;
for (int i = 0; i < apm->rowCount(); i++) {
qDebug() << "aim->Qt::Vertical(" << i << ")" << aim->headerData(i, Qt::Vertical, Qt::DisplayRole);
qDebug() << "apm->Qt::Vertical(" << i << ")" << apm->headerData(i, Qt::Vertical, Qt::DisplayRole);
qDebug() << "transposedModel->Qt::Vertical(" << i << ")" << transposedModel->headerData(i, Qt::Vertical, Qt::DisplayRole);
}
调试是:
aim->Qt::Vertical( 0 ) QVariant(int, 1)
apm->Qt::Vertical( 0 ) QVariant(int, 1)
[ TransposeProxyModel::headerData ] //qDebug in TransposeProxyModel::headerData
transposedModel->Qt::Vertical( 0 ) QVariant(QChar, 'A')
aim->Qt::Vertical( 1 ) QVariant(int, 1)
apm->Qt::Vertical( 1 ) QVariant(int, 1)
[ TransposeProxyModel::headerData ] //qDebug in TransposeProxyModel::headerData
transposedModel->Qt::Vertical( 1 ) QVariant(QChar, 'B')
aim->Qt::Vertical( 2 ) QVariant(int, 1)
apm->Qt::Vertical( 2 ) QVariant(int, 1)
[ TransposeProxyModel::headerData ] //qDebug in TransposeProxyModel::headerData
transposedModel->Qt::Vertical( 2 ) QVariant(QChar, 'C')
所以我猜这就是问题 - 这个方法并不抽象,这也就是为什么它没有调用我的重写方法。 Qt bug?还是故意的?我也看了一眼
C:\ Qt的\ Qt5.2.1 \ 5.2.1 \ SRC \ qtbase \ SRC \ corelib的\ itemmodels \ qabstractproxymodel.cpp
/*!
\reimp
*/
QVariant QAbstractProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
Q_D(const QAbstractProxyModel);
int sourceSection;
if (orientation == Qt::Horizontal) {
const QModelIndex proxyIndex = index(0, section);
sourceSection = mapToSource(proxyIndex).column();
} else {
const QModelIndex proxyIndex = index(section, 0);
sourceSection = mapToSource(proxyIndex).row();
}
return d->model->headerData(sourceSection, orientation, role);
}
我想它应该得到正确的标题 - 它调用mapToSource,这是纯虚拟的,这应该获得正确的索引?