25 июля 2019 г. 16:31

QML Model & C++Model

qml, qt, model

Доброго времни суток! есть модель на C++,которая берет данные из sqlite базы. в файле QML есть listview, в который должны загружаться данные, с листом очень много действий и в такой ситуации не удобно работать с С++ моделью, поскольку нужно регулярно делать апдейт модели данные в делегатах перезатираются что сильно затрудняет работу, а из самой модели данные нужны только на старте. Собственно вопрос, можно ли при старте програмы С++ модель копировать в QML модель чтоб с ней работать динамично, чтоб только в некоторых ситуациях данные записывались в базу и отобразились только при следующем старте программы.
п.с если не понятно описание задавайте вопросы

Возврат 10% от суммы заказа отеля на Booking
Возврат 10% от суммы заказа отеля на Booking
Предлагаем ссылку с 10% возвратом от суммы заказа при бронировании отеля через Booking
4

Добрый день!

А можно код того, как модель C++ регистрируется в QML и как она добавлена в ListView?

main.cpp

 PageModel *page_model=new PageModel();
     engine.rootContext()->setContextProperty("page_model",page_model);

Pagemodel.h

class PageModel : public QSqlQueryModel
{
    Q_OBJECT
public:
    explicit PageModel(QObject *parent = nullptr);

    enum Roles
    {
        idRole= Qt::UserRole+1,
        urlRole,
        nameSiteRole,
        screenRole
    };

    Q_INVOKABLE QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
    Q_INVOKABLE QVariantMap get(int idx) const;

signals:

protected:
    QHash<int,QByteArray> roleNames()const;

public slots:
    void updateModel();
    int getId(int row);
};

PageModel.cpp

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

QVariant PageModel::data(const QModelIndex &index, int role) const
{
    int columnId = role - Qt::UserRole - 1;
    // Создаём индекс с помощью новоиспечённого ID колонки
    QModelIndex modelIndex = this->index(index.row(), columnId);

    /* И с помощью уже метода data() базового класса
     * вытаскиваем данные для таблицы из модели
     * */
    return QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
}

QVariantMap PageModel::get(int idx) const
{
    QVariantMap map;
    foreach(int k, roleNames().keys()) {
        map[roleNames().value(k)] = data(index(idx, 0), k);
    }
    return map;
}

QHash<int, QByteArray> PageModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[idRole]="id";
    roles[urlRole]="url";
    roles[nameSiteRole]="namesite";
    roles[screenRole]="screen";
    return roles;
}

void PageModel::updateModel()
{
    this->setQuery("select id, url, namesite, screen from openTabTable");
}

int PageModel::getId(int row)
{
    return this->data(this->index(row, 0), idRole).toInt();
}

QML

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtWebView 1.13

Item {
    id: idListView1Form
    width: 400
    height: 700

    Rectangle{
        id: rectangleForListView
        y: parent.height * 0.15
        height: parent.height * 0.7
        anchors.left: parent.left
        anchors.right: parent.right

        ListView
        {
            id: myListView1
            highlightRangeMode: ListView.StrictlyEnforceRange
            anchors.fill: parent
            orientation : ListView.Horizontal
            snapMode: ListView.NoSnap
            contentX: 100
            contentWidth: 100
            model: page_model

            delegate:ItemDelegate
            {
                id: itemDelegate
                width : myListView1.width < myListView1.height ? myListView1.width * 0.7 : myListView1.height * 1
                height: myListView1.width < myListView1.height ? myListView1.width * 1 : myListView1.height * 0.7
                Rectangle
                {

                    WebView1
                    {
                        id:webView
                    }

                    anchors.fill: parent
                    anchors.leftMargin: myListView1.width * 0.06
                    Label
                    {
                        id:site_name
                        anchors.top: parent.top
                        anchors.centerIn: parent
                        text: namesite
                    }

                    Rectangle {
                        id: rec1
                        color: "grey"
                        anchors
                        {
                            top:site_name.bottom
                            left: parent.left
                            right:parent.right
                            bottom:parent.bottom
                        }
                        Label
                        {
                            anchors.centerIn: parent
                            text: url
                        }
                    }


                }
                MouseArea
                {
                    id: ma_click
                    anchors.fill: parent
                    onClicked:
                    {
                        webView.url=url
                        stack.push(webView)
                    }
                }
            }
        }
    }
}

Я не уверен, но думаю. что можно ещё переписать метод setData в QSqlQueryModel, в котором записывать данные в базу данных и сразу делать апдейт модели после записи данных в базу данных. Тогда проблема с перезатиранием данных в делегатах будет уже менее актуальна.

Также, как вы и сказали, что данные нужны только при старте, то я бы попробовал написать обычную модель данных. в функции main, забирал бы данные из базы данных в вектор, которые бы устанавливал в ту модель. Тогда уже данные не будут так зависимы от базы данных, как было поначалу.

Ещё можно попробовать с помощью QVariantMap протолкнуть данные до QML и там уже записать в QML модель данных.

Ещё можно попробовать взять данные из базы данных прямо в QML

import QtQuick 2.0

Rectangle {
    color: "white"
    width: 200
    height: 100

    Text {
        text: "?"
        anchors.horizontalCenter: parent.horizontalCenter
        function findGreetings() {
            var db = openDatabaseSync("QDeclarativeExampleDB", "1.0", "The Example QML SQL!", 1000000);

            db.transaction(
                function(tx) {
                    // Create the database if it doesn't already exist
                    tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)');

                    // Add (another) greeting row
                    tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ]);

                    // Show all added greetings
                    var rs = tx.executeSql('SELECT * FROM Greeting');

                    var r = ""
                    for (var i = 0; i < rs.rows.length; i++) {
                        r += rs.rows.item(i).salutation + ", " + rs.rows.item(i).salutee + "\n"
                    }
                    text = r
                }
            )
        }
        Component.onCompleted: findGreetings()
    }
}

Тогда манипуляций в C++ делать не нужно будет.

благодарю, интересное решение

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
D
16 августа 2019 г. 11:58
Damir

C++ - Тест 003. Условия и циклы

  • Результат:92баллов,
  • Очки рейтинга8
D
16 августа 2019 г. 11:46
Damir

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

  • Результат:75баллов,
  • Очки рейтинга2
u
14 августа 2019 г. 13:55
unrealproro

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

  • Результат:83баллов,
  • Очки рейтинга4
Последние комментарии
19 августа 2019 г. 6:41
Андрей Янкович

это проблема дистрибутива, попробуйте установить через пакетный менеджер snap Суть проблемы: libQt5Core которая лежит в дистрибутиве требует версию glibc >= 2.25 у вас видимо …
b
18 августа 2019 г. 5:09
bbb116

cqtdeployer /home/aleks/CQtDeployer/bin/cqtdeployer: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.25' not found (required by /home/aleks/CQtDeployer/lib/libQt5Core.so.5) linux mint …
D
17 августа 2019 г. 8:04
Damir

github ChekableTView Правой групповая смена значения при перетаскивании левой как обычно.
Сейчас обсуждают на форуме
20 августа 2019 г. 12:37
Александр Панюшкин

Добрый день. Я бы хотел добавить, что в вашем коде можно было бы использовать слово auto и цикл for с перебором. Так код получился бы компактнее: auto map = new QMap<Qstring, QString&…
20 августа 2019 г. 12:17
Евгений Легоцкой

Добрый день. Вы делаете некорректную попытку создать исключение. Исключения генерируются кодом, то есть любое исключение, которое вы перехватываете, всегда генерируется оператором th…
20 августа 2019 г. 8:04
IscanderChe

Ещё раз здравствуйте. Собираю Qt-проект с помощью CMake. Применяю к полученному exe-файлу windeployqt. В результате подцепляются почему-то dll-ки, оканчивающиеся в наименованиях на "d": Qt…
20 августа 2019 г. 7:46
IscanderChe

Да, с таргетом тоже работает. Спасибо!
Ищу работу?
14,000.00 руб. - 40,000.00 руб.
Разработчик Qt
Annino, Moscow Oblast, Russia
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