给定填充的ro QList的Qt模型视图

时间:2010-08-03 16:11:49

标签: qt list model view

我得到了xyz的一个神圣的列表(代码说int,只是一个例子)粘在QList(大到可以移动到任何地方)。如何为此创建模型视图?我已经阅读了Qt文档,它告诉我,我必须重新实现dataindexparentrowCountcolumnCount函数。但预处理器/编译器是否需要更多重新实现的功能呢?我已经阅读了Qt Book中的一章,但它也没有帮助。在这里我的黑客代码:

class XModel : public QAbstractListModel
{
Q_OBJECT
public:
    explicit XModel(QList<int> *valuelist, QObject *parent = 0);
    virtual ~XModel();
    int rowCount(const QModelIndex &) const;
    int columnCount(const QModelIndex &) const;
    QModelIndex index( int row, int column, const QModelIndex & parent = QModelIndex()) const;
    QModelIndex parent(const QModelIndex &index) const;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
private:
    QList<int>* blah;
signals:

public slots:

};



XModel::XModel(QList<int> *valuelist, QObject *parent) :
    QAbstractListModel(parent),
    blah(valuelist)
{

}




XModel::~XModel()
{

}



int XModel::rowCount(const QModelIndex &) const
{
    return blah->size();
}

int XModel::columnCount(const QModelIndex &) const
{
    return 1;
}


QModelIndex XModel::index(int row, int column, const QModelIndex &parent) const
{
    return createIndex(row, column, (void)&(blah->at(row)));
}



QModelIndex XModel::parent(const QModelIndex &index) const
{
    return createIndex(index->row(), index->column(), NULL); 
}




QVariant XModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
{
    return QVariant(blah->at(index.row()));
}

我是否必须使用QAbstractItemModelQAbstractListModel以完全相同的方式工作?如何为模型提供实际数据的来源?这仅在data函数内吗?请告诉我我做错了什么,我没有看到它,并就如何正确地做出建议,(好)欢迎欢迎。

这是固定的,但是......

修改

Widget::Widget(QWidget *parent)
    : QWidget(parent),
    valuelist(),
    xm(&valuelist) //xm = XModel
{
    valuelist.append(1);
    valuelist.append(2);
    valuelist.append(3);
    valuelist.append(4);
    valuelist.append(5);
    valuelist.append(6);
    valuelist.append(7);
    valuelist.append(8);
    valuelist.append(9);

    view = new QListView(this);
    view->setModel(&xm);
    //how to force the XModel to reread the QList`?
    view->show();
}

1 个答案:

答案 0 :(得分:4)

添加和删除XModel中的数据并让XModel为您修改基础列表(引用?):

Widget::Widget(QWidget *parent)
    : QWidget(parent),
    valuelist(),
    xm(&valuelist) //xm = XModel
{
    xm.append(1);
    xm.append(2);
    xm.append(3);
    xm.append(4);
    xm.append(5);
    xm.append(6);
    xm.append(7);
    xm.append(8);
    xm.append(9);

    view = new QListView(this);
    view->setModel(&xm);

    xm.append(10); // should call beginInsertRows, append to valuelist, and call endInsertRows.

    Q_ASSERT(valuelist.contains(10));

    view->show();
}

否则,您可以创建QObject和QList的混合,它们可以发出信号以通知XModel变化,但我认为第一种方法更好。

编辑:

这是一个愚蠢的例子。它将创建一个列表支持的模型,该模型将每秒向列表中添加更多元素:

#include <QtGui/QApplication>
#include <QtGui/QListView>
#include <QtCore/QAbstractListModel>
#include <QtCore/QTimer>

class ListBackedModel : public QAbstractListModel
{
    Q_OBJECT
    QList<int>* m_list;

public:

    ListBackedModel(QList<int>* list, QObject* parent = 0)
        : QAbstractListModel(parent)
        , m_list(list)
    {}

    ~ListBackedModel()
    {}

    int rowCount(const QModelIndex &parent = QModelIndex()) const
    {
        Q_UNUSED(parent);
        return m_list->size();
    }

    QVariant data(const QModelIndex &index, int role) const
    {
        if (index.row() >= rowCount()) { return QVariant(); }
        if (index.row() < 0) { return QVariant(); }

        int element = m_list->at(index.row());

        if (Qt::DisplayRole == role) {
            return QString::number(element);
        }

        if (Qt::ToolTipRole == role) {
            return tr("%1 is element #%2").arg(element).arg(index.row() + 1);
        }

        return QVariant();
    }

    void append(int element)
    {
        /*
            First is the new index of the first element that will be inserted.
            Last is the new index of the last element that will be inserted.
            Since we're appending only one element at the end of the list, the
            index of the first and last elements is the same, and is equal to
            the current size of the list.
        */
        int first = m_list->size();
        int last = first;

        beginInsertRows(QModelIndex(), first, last);
        m_list->append(element);
        endInsertRows();
    }

    void startAddingMoreElements()
    {
        QTimer::singleShot(1000, this, SLOT(addMoreElements()));
    }

private slots:

    void addMoreElements()
    {
        append(qrand() % 100);
        startAddingMoreElements();
    }
};


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QList<int> list;
    list << 1 << 10 << 34 << 111;
    ListBackedModel model(&list);

    QListView listView;
    listView.setModel(&model);
    listView.show();

    model.startAddingMoreElements();

    return a.exec();
}

#include "main.moc"