2014-09-26 35 views
1

我有一個問題,以正確轉置我從db接收的表。我沿着找到的路徑here,最後在QAbstractProxyModel的子類中結束 - 就像here所描述的那樣。 可惜的是,它不完全工作,這裏的問題出在哪裏:在QSqlQueryModel(轉置表)中交換標題

我有什麼:

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 

所以,正如你所看到的,數據是正確的轉置,但頭變壞...而我真的需要th EM :(

我試圖手動設定頭數據,但它也失敗:

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計算結果爲假...

任何想法?

固定爲@維尼修斯Gobbo A.奧利維拉指出

+1

這是在這裏深夜...但如果我看到正確的,你想要什麼,你得到的是相同的。也許你想檢查一下; D – 2014-09-26 01:19:57

+0

是的 - 我拼錯了我實際取得的成績。問題是,我在所有列(從第一列)獲取相同的標題,在所有行(從第一行)獲得相同的標題。我無法改變它 - 甚至手動... – murison 2014-09-26 07:12:14

+0

嘿,你的帖子中的鏈接不幸死了,你可以發佈你的完整工作代碼供將來參考? – 2015-08-26 08:28:42

回答

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方法。

+0

我試圖這樣做(寫完全相同的代碼) - 沒有幫助。我在裏面放了一個剎車點 - 它從不觸發。 – murison 2014-09-26 12:34:30

+0

我的上帝我是白癡......我的代碼幾乎完全相同......我錯過了函數聲明中的const ...... – murison 2014-09-26 20:18:25

+0

很高興知道它的工作! ;) – Albert 2014-09-26 20:20:54

0

有趣的事情雖然 - doc指出,這是一個虛擬的方法:

虛擬的QVariant headerData(INT部分,Qt的::取向方向, INT角色)const的

(... )

的QVariant QAbstractProxyModel :: headerData(INT 部,Qt的::取向方位,INT角色)常量[虛]

從QAbstractItemModel :: headerData()重新實現。

但在實際headerthe 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的錯誤?或者是故意的?我也參加了一場不期而遇

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,這是純虛擬的,這應該獲得正確的索引?

+1

在我的設置虛擬是從位置:C:\ Qt \ Qt5.2.1 \ 5.2.1 \ msvc2010_opengl \ include \ QtCore \ qabstractitemmodel.h,行188-189,它是:虛擬QVariant headerData(int節,Qt :: Orientation orientation,int role = Qt :: DisplayRole)const ...所以很好。 – Albert 2014-09-26 15:09:39

+0

我拼錯了文件名 - 請問您可以檢查qabstractproxymodel.h嗎? – murison 2014-09-26 17:58:59

+1

嗨,它沒有在QAbstractProxyModel中聲明爲虛擬的,但它在QAbstractItemModel中,它是它的基類,所以一切都很好。滴滴你從我的答案嘗試完整的代碼,我只是在另一個Qt設置在這裏檢查,它仍然工作得很好。我認爲你有正確的解決方案。 – Albert 2014-09-26 19:33:25