Russian Qt Forum

Qt => Qt Quick => Тема начата: Istrid от Май 27, 2012, 16:21



Название: Проблемы с ListView
Отправлено: Istrid от Май 27, 2012, 16:21
Всем доброго времени суток. Хочу с помощью QML реализовать столбчатую диаграмму. Для это использовал ListView, модель на C++ и делегат к ней на QML. До какого-то момента времени работало замечательно, но недавно обнаружил(диаграмма на отдельной вкладке, редко заглядывал туда), что она поломалась. Причину уже второй день понять не могу. Поломка заключается в том, что рисуется только 1 item модели. Всегда только один. в методе модели Data проходится по всем элементам, отображает только один.

Модель:
Код:
#ifndef TREEMODEL_H
#define TREEMODEL_H

#include <QAbstractListModel>
#include <QDeclarativeContext>
#include <QDeclarativeView>
#include <QDeclarativeEngine>
#include <QDeclarativeComponent>
#include <QDebug>
#include <QDate>
#include <QStandardItemModel>
#include "../../Data/Entyties/transaction.h"
class GraphicsModelItem;
class GraphicsModel : public QAbstractListModel
{
    Q_OBJECT
public:
    explicit GraphicsModel(QDeclarativeView *view, QObject *parent=0);
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    int rowCount(const QModelIndex &parent = QModelIndex()) const;

    QList<GraphicsModelItem *> items;
    int amount_length;
    int amount_max;
    int date_height;
    Account *current_acc;
    QMap<QDate,GraphicsModelItem*> *map;
    QDeclarativeView *view;
public slots:
    void ItemsFromTransactions(QList<Transaction*> *l, Account *acc);
private:
    Q_DISABLE_COPY(GraphicsModel)

    enum ListMenuItemRoles
    {
        IncomeRole = 10,
        OutcomeRole = 20,
        CountRole = 30,
        DateRole = 40,
        DayCountRole = 50
    };
};
#endif // TREEMODEL_H

Код:
#include "GraphicsModel.h"

class GraphicsModelItem
{
public:
    GraphicsModelItem(int income, int outcome, int number, QDate date)
    {
        this->income = income;
        this->outcome = outcome;
        this->count = number;
        this->date = date;
    }
    int income;
    int outcome;
    int count;
    QDate date;
};

GraphicsModel::GraphicsModel(QDeclarativeView *view, QObject *parent) :
    QAbstractListModel(parent)
{
    QHash<int, QByteArray> roles = roleNames();
    roles.insert(IncomeRole, QByteArray("income"));
    roles.insert(OutcomeRole, QByteArray("outcome"));
    roles.insert(CountRole, QByteArray("count"));
    roles.insert(DateRole, QByteArray("date"));
    roles.insert(DayCountRole, QByteArray("dayCount"));
    setRoleNames(roles);
    amount_max = 0;
    amount_length = 1;
    this->view = view;
    this->view->setSource(QUrl("qrc:/QML/GraphView"));
    this->view->rootContext()->setContextProperty("GraphModel",this);
    this->view->rootContext()->setContextProperty("amount_length", amount_length);
    this->view->rootContext()->setContextProperty("amount_max", amount_max);
    this->view->setResizeMode(QDeclarativeView::SizeRootObjectToView);
    /*this->view->setCacheMode(QGraphicsView::CacheBackground);
    this->view->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
    this->view->setOptimizationFlags(QGraphicsView::DontSavePainterState|QGraphicsView::DontAdjustForAntialiasing);
*/}
void GraphicsModel::ItemsFromTransactions(QList<Transaction*> *l,Account *acc)
{
    this->current_acc = acc;
    amount_max = 0;
    QMap<QDate,GraphicsModelItem*> map;

    for (int i=0; i<l->size();i++)
    {
        Transaction* tr = l->at(i);
        if (map.contains(l->at(i)->created_at().date()))
        {
            GraphicsModelItem* item = map.value(tr->created_at().date()) ;
            if (tr->acc_from()==current_acc)
                item->outcome+=tr->amount_from();
            else
                item->income+=tr->amount_to();
        }else
        {
            GraphicsModelItem* item ;
            if (tr->acc_from()==current_acc)
                item = new GraphicsModelItem(0,tr->amount_from(),map.size(),tr->created_at().date());
            else
                item = new GraphicsModelItem(tr->amount_to(),0,map.size(),tr->created_at().date());
            map.insert(tr->created_at().date(),item);
        }
    }

    this->items.clear();
    QList<GraphicsModelItem*> ll = map.values();
    for (int i=0;i<ll.length();i++)
    {
        if (ll.at(i)->income>amount_max)
            amount_max = ll.at(i)->income;

        if (ll.at(i)->outcome>amount_max)
            amount_max = ll.at(i)->outcome;

        this->items.push_back(ll.at(i));
    }

    qDebug() <<"size of elements " << items.size();
    if (items.size()>0)
    {
        amount_length = QString().setNum(amount_max).length()+1;
        this->view->rootContext()->setContextProperty("GraphModel",this);
        this->view->rootContext()->setContextProperty("amount_length", amount_length);
        this->view->rootContext()->setContextProperty("amount_max", amount_max);
        this->reset();
    }
}


QVariant GraphicsModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();
    if (index.row() > (items.size()-1) )
        return QVariant();
    GraphicsModelItem *item = items.at(index.row());
    qDebug()<< " items row = "<< index.row();
    switch (role)
    {
        case Qt::UserRole:
        {
            case IncomeRole:
                return QVariant::fromValue(item->income);
            case OutcomeRole:
                return QVariant::fromValue(item->outcome);
            case CountRole:
            qDebug()<< " items size = "<< items.size();
            qDebug()<< " item count = " <<item->count;
                return QVariant::fromValue(index.row());
            case DateRole:
                return QVariant::fromValue(item->date.toString("dd.MM"));
            case DayCountRole:
                return QVariant::fromValue(items.size());
        }
    }
    return QVariant();
}

int GraphicsModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return items.size();
}

часть QML, отвечающая за отображение:
Код:
ListView
        {
            id: graphicView
            delegate: dayActivity
            model: GraphModel


            Rectangle {
                id: yLine
                width: 1
                height: myGraphic.height-mainRect.adaptFontSize()*2
                x: mainRect.adaptFontSize()*amount_length/1.5
                color: "black"
            }
            Rectangle {
                id: xLine
                x: yLine.x
                height: 1
                width: myGraphic.width
                y: yLine.height;
                color: "black"
            }
}
            Component {
                    id: dayActivity
                    Item {

                        Item {
                            visible: false
                            id: levelMarginElement
                            x:0
                            y:0
                            height:1
                            width:10*count //count*((myGraphic.width-yLine.x)/100)+5 + yLine.x
                        }
                        Rectangle
                        {

                            id: incomeRect
                            radius: 10
                            height: (xLine.y-myGraphic.height*0.03)/amount_max * income
                            x:levelMarginElement.width
                            y:xLine.y-height+2
                            width:(myGraphic.width-yLine.x)*0.9/(dayCount*2)

                            color: "red"
                        }

                        Rectangle
                        {
                            id: outcomeRect
                            radius: 10
                            height: (xLine.y-myGraphic.height*0.03)/amount_max * outcome
                            x:levelMarginElement.width+incomeRect.width-1
                            y: xLine.y-height+2
                            width:(myGraphic.width-yLine.x)*0.9/(dayCount*2)

                            color: "blue"
                        }
                        Text
                        {
                            id:dateText
                            x:outcomeRect.x-mainRect.adaptFontSize()
                            y:xLine.y+2
                            text:date
                            font.pixelSize: mainRect.adaptFontSize()+1
                        }
                    }
            }


Название: Re: Проблемы с ListView
Отправлено: BlackSoul от Май 28, 2012, 07:47
проверь высоту делегата и самой вьюхи