无法使用QTableView和继承自QAbstractTableModel的子类查看所有Colums

时间:2015-07-25 19:18:06

标签: c++ qt inheritance

我正在学习Qt。

此代码大部分来自一本书(构建Qt应用程序的艺术)

我的目标:我正在尝试创建一个继承自QAbstractTableModel的简单地址簿模型。我已经实现了rowCount(),columnCount(),data(),headerData(),index()和parent()。

问题:当我调用QTableView时,只显示第一列。 我会发布一个输出图像,但我从来没有真正回答过这些问题。抱歉。

But the output looks something like this:   
 __________________
|_____Lead________|
|Jim Grayson      |
|Prescilla Winston|
|Melissa Potter   |
|_________________|

It should look something like this:
_________________________________________________________
|_____Lead________|____Title_____|__Phone____|___Notes___|
|Jim Grayson      |     ...      |           |           |
|Prescilla Winston|              |   ....    |           |
|__Melissa Potter_|______________|___________|____...___ |

这是我尝试运行的小.csv文件

db_small.csv:

Lead/Title/Phone/Notes
Jim Grayson/Senior Manager/(555)761-2385/"Spoke Tuesday, he's interested"
Prescilla Winston/Development Director/(555)218-3981/said to call again next week
Melissa Potter/Head of Accounts/(555)791-3471/"Not interested, gave referral"

AddresModel.h:

#ifndef ADDRESSMODEL_H
#define ADDRESSMODEL_H

#include <QtGui>
#include <QtCore>

class AddressModel : public QAbstractTableModel{

private:
    QList<QStringList> addressBook;
    void splitCVSLines(QString &);
public:
    AddressModel(QString& addresses, QObject* parent = 0);
    int rowCount(const QModelIndex & parent = QModelIndex()) const;
    int columnCount(const QModelIndex & parent = QModelIndex()) const;
    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
    QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
    QModelIndex parent(const QModelIndex & index) const;
};
#endif

AddressModel.cpp

#include "AddressModel.h"
#include <iostream>


AddressModel::AddressModel(QString & addresses, QObject* parent ) 
        : QAbstractTableModel(parent){
    splitCVSLines(addresses);
}


void AddressModel::splitCVSLines(QString & addresses){
    QStringList records = addresses.split('\n');
    QStringList line;
    foreach(QString record, records){
        addressBook.append(record.split('/'));
    }
    foreach(QStringList strlist, addressBook){
        foreach(QString str, strlist){
            std::cout<<"..."<<str.toStdString()<<"...";

        }
        std::cout<<std::endl;
    }
}

int AddressModel::rowCount(const QModelIndex & parent) const{
    Q_UNUSED(parent);
    return addressBook.count() -2;
}

int AddressModel::columnCount(const QModelIndex & parent) const{
    Q_UNUSED(parent);
    return (addressBook[0].size());
}


QVariant AddressModel::data(const QModelIndex & index, int role) const{
    if(!index.isValid()){
        return QVariant();
    }
    //We are working with the row, always
    QStringList addressRecord = addressBook.at(index.row() +1);
    if(role == Qt::DisplayRole || role == Qt::EditRole){
        return addressRecord.at(index.column());
    }
    if(role == Qt::ToolTipRole){
        QString returnTip, key, value;
        returnTip = "<qt><table>";
        for (int i = 0; i < addressRecord.count(); ++i){
            key = this->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString();
            value = addressRecord.at(i);
            if(!value.isEmpty()){
                returnTip += QString("<tr><td><b>%1</b>: %2</td></tr>").arg(key, value);
            }
        }
        returnTip += "</table></qt>";
        return returnTip;
    }
    return QVariant();
}

QVariant AddressModel::headerData(int section, Qt::Orientation orientation,
        int role) const{
    if(orientation == Qt::Horizontal){
        if(role == Qt::DisplayRole){
            return (addressBook[0]).at(section);
        }
    }
    return QAbstractTableModel::headerData(section, orientation, role);
}

QModelIndex AddressModel::index(int row, int column, const QModelIndex & parent) const{
    Q_UNUSED(parent);
    return QAbstractTableModel::createIndex(row, column);
}

QModelIndex AddressModel::parent(const QModelIndex & index) const{
    Q_UNUSED(index);
    return QModelIndex();
}

main.cpp

#include <QApplication>
#include <iostream>
#include <fstream>
#include <QtGui>
#include <QtCore>
#include "AddressModel.h"

using namespace std;

    int main(int argc, char *argv[]){
        if(argc != 2){
            return std::cerr<<"No!"<<std::endl;
        }
        QApplication a(argc,argv);

        ifstream file;

        file.open(argv[1]);
        string line;
        string alltext;
        while(file){
            getline(file, line);
            alltext += "\n";
            alltext += line;
        }
        file.close();
        QString filetext(QString::fromStdString(alltext));
        AddressModel g(filetext);

        QTableView table;
        table.setModel(&g);
        table.show();

        return a.exec();
    }

1 个答案:

答案 0 :(得分:0)

解决方案: 在main.cpp中,swop while循环中的行。

while(getline(file, line)){
  alltext += line;
  alltext += "\n";
}

说明:

只显示第一列,因为您的columnCount函数当前正在返回1.

在main函数内的while循环中,您将在alltext字符串的开头添加一个'\ n'字符。在splitCVSLines函数中,首先用'\ n'字符分割..所以当循环记录时,第一个记录的列数为1,而其余记录的列数为4.

通过在while循环中交换两行,第一条记录将不再是空行,因此columnCount函数将返回4,从而导致显示所有数据。

我还将getline移动为while循环的条件..这有助于防止最后一条记录显示两次..

希望这会有所帮助。