Barry Michael Doyle
Barry Michael Doyle

Reputation: 10588

How to Populate a QStandardItemModel

I'm a beginner at Qt and I'm struggling to populate a QStandardItemModel from an XML file.

I've tried the following and the entire project runs successfully but the QtableView does not display the data.

Here is my main.cpp:

void readXml(const QString& fileName) {
    QFile file(fileName);
    if(!file.open(QFile::ReadOnly | QFile::Text)) {
        qDebug() << "Cannot read file" << file.errorString();
        return;
    }

    StockItems* stockitems = new StockItems;
    XmlStockItemsReader xmlReader(stockitems);

    if(!xmlReader.read(&file))
        qDebug() << "Parse error in file " << xmlReader.errorString();
    else {
        stockitems->print();
        stockitems->populateStockModel();
    }
}

int main(int argc, char* argv[]) {
    QApplication app(argc, argv);
    StockItems si;

    //! Change this to match the path of your project
    QString path = "C:\\unisa\\cos3711\\FIConcession";
    readXml(path + "\\stockitems.xml");

    si.show();

    return app.exec();
}

In stockitems.cpp I have the following function:

void StockItems::populateStockModel() {
    foreach(Item* item, m_items) {
        QList<QStandardItem*> newRow;

        QStandardItem *stockID = new QStandardItem(QString("%1").arg(item->stockID()));
        QStandardItem *desc = new QStandardItem(QString("%2").arg(item->desc()));
        QStandardItem *price = new QStandardItem(QString("%3").arg(item->price()));

        newRow.append(stockID);
        newRow.append(desc);
        newRow.append(price);

        stockModel->appendRow(newRow);
    }
}

If I do some debugging I can see that the stockID, desc and prices are correctly read, so the problem must lie somewhere with updating the stockModel.

My main StockItems Constructor is as follows:

StockItems::StockItems(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::StockItems)
{
    ui->setupUi(this);
    stockModel = new QStandardItemModel(0, 3);

    // Set Model Headers
    stockModel->setHeaderData(0, Qt::Horizontal, "Stock ID", Qt::DisplayRole);
    stockModel->setHeaderData(1, Qt::Horizontal, "Description", Qt::DisplayRole);
    stockModel->setHeaderData(2, Qt::Horizontal, "Price", Qt::DisplayRole);

    // Link Model to Table View
    ui->tvStock->setModel(stockModel);
}

I have an add button which contains the following onclick code which works as expected so I'm just not sure if I'm referencing the stockModel correctly.

QList<QStandardItem*> newRow;

QStandardItem* stockID = new QStandardItem(QString("%1").arg(ui->tbStockId->text()));
QStandardItem* desc = new QStandardItem(QString("%2").arg(ui->tbDesc->text()));
QStandardItem* price = new QStandardItem(QString("%3").arg(ui->sbPrice->text()));

newRow.append(stockID);
newRow.append(desc);
newRow.append(price);

stockModel->appendRow(newRow);

Finally I think this might help, my stockitems.h file:

class StockItems : public QDialog
{
    Q_OBJECT

public:
    explicit StockItems(QWidget *parent = 0);
    ~StockItems();
    void populateStockModel();
    void addItem(Item* item);
    void print() const;

private slots:
    void on_btnAdd_clicked();
    void on_btnDelete_clicked();

private:
    Ui::StockItems *ui;
    QStandardItemModel *stockModel;
    QList<Item*> m_items;
};

This is a lot and please let me know if I should provide anything else but I'm really lost as to how to populate this model correctly.

Thanks for any guidance!

Upvotes: 0

Views: 1568

Answers (1)

E4z9
E4z9

Reputation: 1767

Your readXml function does not populate the StockItems instance that you create in your main function, but a completely new StockItems instance that isn't used anywhere.

For example, instead of

StockItems* stockitems = new StockItems;

in your readXml function, let readXml take another StockItems argument, and use that:

void readXml(const QString& fileName, StockItems *stockItems) {
    // do everything here as before, except for the
    // StockItems* stockitems = new StockItems;
    ...
}

int main(int argc, char* argv[]) {
    ...
    readXml(path + "\\stockitems.xml", &si);
    si.show();
    ...
}

Upvotes: 1

Related Questions