Qt Model View для данного заполненного ro QList - PullRequest
0 голосов
/ 03 августа 2010

я получил годовой список xyz (код говорит, что int, просто пример), склеенный в QList (чтобы переместиться куда угодно). Как я могу создать модель для этого? Я уже прочитал документацию Qt, в которой говорится, что я должен переопределить функции data, index, parent, rowCount, columnCount. Но препроцессор / компилятор требует больше переопределенных функций? Я уже прочитал главу в моей книге Qt, но это тоже не помогло. Вот мой взломанный код:

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()));
}

Мне даже нужно использовать QAbstractItemModel или QAbstractListModel работает точно так же? Как дать модели источник фактических данных? Это только в функции data? Пожалуйста, скажите мне, что я делаю неправильно, я не вижу этого и даю советы, как это сделать правильно, (хорошо), как добро пожаловать.

Это исправлено, но ...

EDIT:

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 Ответ

4 голосов
/ 03 августа 2010

Добавьте и удалите данные из 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 об изменениях, но я думаю, что первый подход лучше.

Edit:

Вот глупый пример. Это создаст модель на основе списка, которая будет добавлять больше элементов в список каждую секунду:

#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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...