m
10 января 2019 г. 15:00

QML C++

ListView, height

Добрый вечер.
Написал свою модель на основе QAbstractListModel как тут .
Все заработало но у меня элементов больше чем в примере. Соответственно не все помещаются в область ограниченную высотой height:200. При прокрутке списка оставшиеся элементы вне поля видимости не подгружаются.При увелечении height элементов становится больше.
Вопрос.
Как правильно задать параметр height?

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
23
m

Забыл добавить.
Все это дела поместил в заранее сформированный QWidget с помощью QQuickWidget а не QQuickView как в примере

0

Попробуйте сначало создать квадрат нужных размеров, а потом поместить список и задать параметр заполнить родителя.

п.с. У вас таки интерфейс на виджетах или qml?

0

Добрый день!

Думаю, что здесь ещё нужно поместить всё в ScrollArea, чтобы были полосы прокрутки.

0
m

Добрый вечер. Постепенно перевожу с виджета на QML

0
m

Полосу прокрутки добовляю с помощью ScrollBar.vertical: ScrollBar {} она то появляется. Вопрос то в другом.
Вот например

    ListView {
        width: 160
        height: 240

        model: 100

        delegate: ItemDelegate {
            text: modelData
            width: parent.width

        }

        ScrollIndicator.vertical: ScrollIndicator { }
    }

Элементы не попавшие в область появляются при прокрутке скрола.
У меня же количества объектов на прямую зависит от высоты ListView.
Выстовляю например height:100 подгружается 10 наименований и далее пустота. или 200 тогда 25 наименований
Как я понимаю ListView должена знать либо общее количество объектов жевущий в модели либо должен уметь при прокрутке их подгружать из модели.

0

сделайте отдельно область, и в эту область всуньте список.
пример из проекта, список заполняется из QSqlQueryModel, количество элемнтов может быть разное, каждый элемент списка представляется чекбоксом

    Rectangle
            {
                id: events_arch
                anchors.top: top_rect_arch.top
                anchors.bottom: top_rect_arch.bottom
                anchors.left: select_arch.right
                anchors.right: parent.right
                anchors.margins: 5
                color: style.secondMainColor

                ListView {
                    id: tableView
                    anchors.fill: parent
                    anchors.margins: 5
                    model: eventModel

                    highlight: highlight
                    delegate: CheckBox
                    {
                        id: ch_m
                        text: N+" "+ " "+ENG_TEXT
                        indicator: Rectangle
                        {
                            anchors.verticalCenter: parent.verticalCenter
                            implicitHeight:16
                            implicitWidth:16
                            radius: 3
                            color:style.textColor
                            border.color: style.mainBorderColor
                            border.width: 1

                            Rectangle {
                                visible: checked
                                color: style.greenColor
                                border.color: "#333"
                                radius: 1
                                anchors.margins: 4
                                anchors.fill: parent
                            }
                        }
                        contentItem: Text
                        {
                            leftPadding: ch_m.indicator.width + 4
                            color: "#d0d0d0"
                            text:ch_m.text
                            horizontalAlignment: Text.AlignLeft
                            verticalAlignment: Text.AlignVCenter
                        }
                        onCheckedChanged:
                        {
                            n_event+=N+','
                        }
                    }
                }
            }

список берет все что есть в моделе

1

Добавлю только, что может ещё понадобиться использовать clip: true в Rectangle или ListView, а то могут элементы вылезать за границы парента

0

благодарю, учту

1
m

Все равно не пойму. Если статически набиваю все работает

ListModel {
        id:productListModel1
        ListElement {

        }
        ListElement {

        }
        ListElement {

        }
        ListElement {

        }
        ListElement {

        }
        ListElement {

        }

    }

Если динамически то показывает один элемент. Хотя отладчик говорит что в модели живет 10.

0
m
Rectangle {
    id: mainTabLayout
    clip: true
    ListView {
        id: view
        anchors.fill: parent
         cacheBuffer: 100 * 10
         anchors.margins: 10
         spacing: 10
         model: productListModel
        delegate: Rectangle {
            id: delegateproduct
            width: view.width
            height: 50
            color: "orange"   
        }
      ScrollBar.vertical: ScrollBar {}
    }

}

Выстовляю значение mainTabLayout напримет height: 300 отображаются уже 5 элементов.

0

от куда берете данные?

0
m

.h

#include <QAbstractListModel>
#include <QJsonObject>

class ProductListItem
{
public:
    ProductListItem(const QString &imgresurs, const QString &article,const QString &name_article);

    QString imgresurs() const;
    QString article() const;
    QString name_article() const;

private:
    QString m_imgresurs;
    QString m_article;
    QString m_name_article;
};


class ProductListModel : public QAbstractListModel
{
    Q_OBJECT

public:
    explicit ProductListModel(QObject *parent = nullptr);

    enum Roles{
        NameArticleRole = Qt::UserRole+1,
        ArticleRole,ImgResursRole,PriseRole
    };

    // Basic functionality:
    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;

    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

    // Editable:
    virtual bool setData(const QModelIndex &index, const QVariant &value,int role = Qt::EditRole)  override;

   void addItem(const ProductListItem &item);


protected:

    virtual QHash<int, QByteArray> roleNames() const override;

private:

    QList<ProductListItem> m_data;

};

.cpp

ProductListItem::ProductListItem(const QString &imgresurs, const QString &article,const QString &name_article)
    : m_imgresurs(imgresurs), m_article(article), m_name_article(name_article)
{
}

QString ProductListItem::imgresurs() const
{
    return m_imgresurs;
}

QString ProductListItem::article() const
{
    return m_article;
}

QString ProductListItem::name_article() const
{
    return m_name_article;
}




ProductListModel::ProductListModel(QObject *parent)
    : QAbstractListModel(parent)
{
}

int ProductListModel::rowCount(const QModelIndex &parent) const
{
    // For list models only the root node (an invalid parent) should return the list's size. For all
    // other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
    Q_UNUSED(parent);
       return this->m_data.count();

}

QVariant ProductListModel::data(const QModelIndex &index, int role) const
{


     const ProductListItem item = this->m_data.at(index.row());

    switch (role) {
      case ArticleRole:
          return QVariant(item.article());
      case ImgResursRole:
        return QVariant("item.imgresurs());
      case  NameArticleRole:
        return QVariant(item.name_article());
      default:
          return QVariant();
      }

}

bool ProductListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{


    return false;
}

void ProductListModel::addItem(const ProductListItem &item)
{

    beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_data << item;
        endInsertRows();
}

QHash<int, QByteArray> ProductListModel::roleNames() const
{
    QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
       roles[NameArticleRole] = "name_article";
       roles[ArticleRole] = "article";
       roles[ImgResursRole] = "imgresurs";
       return roles;
}

тут собственно вызываю

   ProductListModel model;
   // Наполняем модель
   for(int i = 0; i<array->count();i++){
       QJsonObject obj = array->at(i).toObject();
       model.addItem(ProductListItem(obj["img"].toString(),
                                     obj["article"].toString(),
                                     obj["name_article"].toString()));
   }

    this->m_quickWidget = new QQuickWidget(this) ;
    this->m_quickWidget->engine()->rootContext()->setContextProperty("productListModel",&model);
    this->m_quickWidget->setSource(QUrl("qrc:/Category.qml"));
    this->m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
    ui->gridLayout_2->addWidget(this->m_quickWidget, 1, 0);
0

получается вы парсите некий жисоновский массив и хотите вывести с него данные, что хотите получить в результате в списке? и почему у вас в делегате просто оранжевые прямоугольники, почему сразу не пытаетесь вывести нужные данные? и что у вас приходит в жисоне?поскольку такой простенький вариант выводит список без проблем

import QtQuick 2.12
import QtQuick.Controls 1.4
import QtQuick.Controls 2.2
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    Rectangle
    {
        anchors.fill: parent

        id: mainTabLayout
        clip: true
        ListView {
            id: view
            anchors.fill: parent
             cacheBuffer: 100 * 10
             anchors.margins: 10
             spacing: 10
             model:["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28"]
            delegate: Rectangle {
                id: delegateproduct
                width: view.width
                height: 50
                color: "orange"
            }
          ScrollBar.vertical: ScrollBar {}
        }
    }
}

копайте в сторону вашей модели и проверьте данные которые приходят и которые находятся самой модели

0
m

"почему у вас в делегате просто оранжевые прямоугольники" упростил для показа код.

0
m

Не пойму что не так).

0
m

Проблема явно с моделью.

0
m

Отрисовывается только первый элемент модели. Который показан в отладочной информации.

0

а у вас модель заполняется в main.cpp? если да, попробуйте данную реализацию вынести в функцию класса создания модели, и вызывать наполнение модели в конструкторе класса.

пример (конструктор модели из предыдущего кода)

EventSqlModel::EventSqlModel(QObject *parent): QSqlQueryModel(parent)
{
    this->updateModel();
}

void SqlQueryModel::updateModel()
{
    QSqlQueryModel::setQuery(query);
    generateRoleNames();
}
0
m

Модель наполняется не в main. Наполнение производится по сигналу из дерева категорий

0
m

Интересно что virtual QVariant data срабатывает только один раз хотя m_data>1

0
m

Ладно не буду вас отвлекать повожусь сам. Спасибо)

0

мне уже и самому интересно.
перенесите "setContextProperty("productListModel",&model)" в main.cpp
простенький пример можно посмотреть тут а это помогло мне когда разбирался с моделями

1
m
  • 13 января 2019 г. 11:52
  • Ответ был помечен как решение.

И так может кому будет интересно решил свою проблему следующим путем.
Через дизайнер в базовый виджет добавил QQuickWidget (назвал его listProducts)
Это соответственно убрал.

 this->m_quickWidget = new QQuickWidget(this) ;
    this->m_quickWidget->engine()->rootContext()->setContextProperty("productListModel",&model);
    this->m_quickWidget->setSource(QUrl("qrc:/Category.qml"));
    this->m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
    ui->gridLayout_2->addWidget(this->m_quickWidget, 1, 0);

а вместо написал

ui->listProducts->engine()->rootContext()->setContextProperty("productListModel",model);
    ui->listProducts->setSource(QUrl("qrc:/Category.qml"));
    ui->listProducts->setResizeMode(QQuickWidget::SizeRootObjectToView);

и все заработало) Всем спасибо.

2

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
G
24 июля 2019 г. 4:20
G0tzef

C++ - Тест 005. Структуры и Классы

  • Результат:66баллов,
  • Очки рейтинга-1
VK
24 июля 2019 г. 3:49
Viktoriia Komarova

C++ - Тест 001. Первая программа и типы данных

  • Результат:40баллов,
  • Очки рейтинга-8
G
24 июля 2019 г. 3:25
G0tzef

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80баллов,
  • Очки рейтинга4
Последние комментарии
23 июля 2019 г. 12:14
IscanderChe

Вот ссылка: https://github.com/iscander-che/TestReportViewer .
23 июля 2019 г. 5:42
Евгений Легоцкой

Хорошо, хотя конечно это С, а не С++ )))) Но если вдруг будут проблемы, то решение через класс со статическими переменными вы видели ))
23 июля 2019 г. 5:33
IscanderChe

"Не потребует каждый раз объявлять extern в других файлах". И так не требует. У меня в тестовом классе эти переменные используются без дополнительного объявления. Так же объявил их в cpp-файле о…
23 июля 2019 г. 5:28
IscanderChe

В репозиторий могу сегодня вечером выложить. "Или ее надо компилить самому под дистриб?" Тут я не совсем понимаю, что вы имеете ввиду. Я выложу в репозиторий исходный код утилиты, и всё.
23 июля 2019 г. 4:32
Евгений Легоцкой

Есть комментарий по вашему коду. Лучше бы вместо глобальных переменных в стиле Си, то есть с использоавнием extern, написали бы статические переменные в рамках класса. IMHO - это будет выглядеть…
Сейчас обсуждают на форуме
24 июля 2019 г. 4:57
Михаиллл

Это не помогает. Ниже мой код Rectangle{ //Flickable { //contentX: 100 id: rectangleForListView y: parent.height * 0.15 height: parent.height * 0.…
24 июля 2019 г. 3:17
Евгений Легоцкой

Ну вот теперь я несколько в ступоре. Запустите из консоли проект и посмотрите тогда, на что ругается. Также, следовало бы посмотреть в настройках самой виртуальной машины, что по поддержке OpenG…
23 июля 2019 г. 8:20
Михаиллл

Так работает QFile f1(dbAdress); f1.setPermissions(QFileDevice::WriteOther);
23 июля 2019 г. 7:11
Pavel K.

Советую использовать нечто такое или такое
22 июля 2019 г. 10:50
Pavel K.

Благодарю.Буду пробовать.
Ищу работу?
5,000.00 руб. - 15,000.00 руб.
Дизайнер
Moskovskiy, Moscow, Russia
25,000.00 руб. - 30,000.00 руб.
Разработчик Qt/C++
Barnaul, Altai Krai, Russia

Для зарегистрированных пользователей на сайте присутствует минимальное количество рекламы

EVILEG
О нас
Услуги
Присоединяйтесь к нам
© EVILEG 2015-2019
Рекомендует хостинг TIMEWEB