Инструменты пользователя

Инструменты сайта


develop:qt:quick3

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
develop:qt:quick3 [2021/08/31 17:00]
admin
develop:qt:quick3 [2021/09/04 10:55] (текущий)
admin
Строка 734: Строка 734:
 === Экспорт объектов и виджетов из C++ в QML === === Экспорт объектов и виджетов из C++ в QML ===
 ---- ----
-Пример экспорта, создаем C++ класс, в конструкторе делаем загрузку и отображение QML формы, виджетом и создаем несколько локальных объектов, которые экспортируются в QML форму, так же экспортируется и объект самого класса (this), определяем слот, все это будет доступно в QML форме.\\+Пример экспорта, создаем C++ класс, в конструкторе делаем загрузку и отображение QML формы, виджетом и создаем несколько локальных объектов, которые экспортируются в QML форму, так же экспортируется и объект самого класса (this), определяем слот, все это будет **доступно в QML форме**.\\
  
 <details> <details>
Строка 740: Строка 740:
 **Файл класса myWidget.cpp** **Файл класса myWidget.cpp**
 <code cpp-qt> <code cpp-qt>
 +#include "mywidget.h"
  
 +MyWidget::MyWidget(QWidget *parent): QWidget(parent)
 +{
 +    QQuickWidget *pv= new QQuickWidget(this);
 +    pv->setSource(QUrl("qrc:/main.qml"));
 +
 +    QVBoxLayout *pvbx= new QVBoxLayout(this);
 +    pvbx->addWidget(pv);
 +    setLayout(pvbx);
 +
 +    QQmlContext *pcon= pv->rootContext();
 +    QStringList lst;
 +    for(int i= 0; i < 100; i++)
 +        lst << "Item"+ QString::number(i);
 +    QStringListModel *pmodel= new QStringListModel(this);
 +    pmodel->setStringList(lst);
 +
 +    pcon->setContextProperty("myModel", pmodel);
 +    pcon->setContextProperty("myText", "It's my text");
 +    pcon->setContextProperty("myColor", QColor(Qt::yellow));
 +    pcon->setContextProperty("myWidget", this);
 +}
 +
 +void MyWidget::slotDisplayDialog()
 +{
 +    QMessageBox::information(0, "Title Message", "Text in message");
 +}
 </code> </code>
 +
  
 **Форма QML** **Форма QML**
 <code QML> <code QML>
 +import QtQuick 2.8
  
 +Rectangle
 +{
 +    width: 200; height: 200;
 +    color: myColor
 +    Text
 +    {
 +        anchors.centerIn: parent
 +        text: myText
 +    }
 +    ListView
 +    {
 +        anchors.fill: parent
 +        model: myModel
 +        delegate: Text { text: model.display }
 +    }
 +    MouseArea
 +    {
 +        anchors.fill: parent
 +        onPressed:
 +        {
 +            myWidget.setWindowTitle("Hello from QML");
 +            myWidget.slotDisplayDialog();
 +        }
 +    }
 +}
 </code> </code>
 </details> </details>
- 
  
    
-=== Использов зарегистр объектов C++ в QML ===+=== Использование зарегистр объектов C++ в QML ===
 ---- ----
 +Как я понял, это передача в QML только **конкретных свойств и методов**, определенных директивами **Q_PROPERTY** и **Q_INVOKABLE** соответственно.\\ 
 +Прежде всего производим регистрацию нашего класса, функцией **qmlRegisterType<T>()**, в нее передается идентификатор модуля (похоже собственный), два параметра с номерами версии, и собсна имя самого класса.\\
  
 <details> <details>
-<summary>:!: Пример: </summary>+<summary>:!: Пример: Передача свойств, методов и сигналов класса в QML</summary> 
 +**Calculate.h** 
 +<code cpp-qt> 
 +#ifndef CALCULATION_H 
 +#define CALCULATION_H 
 + 
 +#include <QObject> 
 + 
 +class Calculation : public QObject 
 +
 +    Q_OBJECT 
 +private: 
 +    Q_PROPERTY(qulonglong input WRITE setInputValue 
 +                                READ inputValue 
 +                                NOTIFY inputValueChanged) // Уведомление об изменении 
 +    Q_PROPERTY(qulonglong result READ resultValue 
 +                                 NOTIFY inputValueChanged) 
 +    qulonglong m_nInput; 
 +    qulonglong m_nResult; 
 + 
 +public: 
 +    explicit Calculation(QObject *parent = nullptr); 
 + 
 +    Q_INVOKABLE qulonglong factorial(const qulonglong &n); 
 +    qulonglong inputValue() const; 
 +    void setInputValue(const qulonglong&); 
 +    qulonglong resultValue() const; 
 + 
 +signals: 
 +    void inputValueChanged(qulonglong); 
 +    void resultValueChanged(qulonglong); 
 +}; 
 + 
 +#endif // CALCULATION_H 
 +</code> 
 + 
 + 
 +**Calculate.cpp** 
 +<code cpp-qt> 
 +#include "calculation.h" 
 + 
 +Calculation::Calculation(QObject *parent) : QObject(parent), m_nInput(0), m_nResult(1) 
 +
 +
 + 
 +qulonglong Calculation::factorial(const qulonglong &n) 
 +
 +    return n ? (n * factorial(n-1)) : 1; 
 +
 + 
 +qulonglong Calculation::inputValue() const 
 +
 +    return m_nInput; 
 +
 + 
 +qulonglong Calculation::resultValue() const 
 +
 +    return m_nResult; 
 +
 + 
 +void Calculation::setInputValue(const qulonglong &n) 
 +
 +    m_nInput= n; 
 +    m_nResult= factorial(m_nInput); 
 +    emit inputValueChanged(m_nInput); 
 +    emit resultValueChanged(m_nResult); 
 +
 +</code> 
 + 
 +**main.cpp** 
 +<code cpp-qt> 
 +#include <QGuiApplication> 
 +#include <QQmlApplicationEngine> 
 +#include "calculation.h" 
 + 
 +int main(int argc, char** argv) 
 +
 +    QGuiApplication app(argc, argv); 
 +    qmlRegisterType<Calculation>("my.class.Calc", 1, 0, "Calculatoin"); 
 +    QQmlApplicationEngine engine; 
 +    engine.load(QUrl("qrc:/main.qml")); 
 + 
 +    return app.exec(); 
 +
 +</code> 
 + 
 + 
 +**Два варианта** реализации, свойствами и методом
 <code QML> <code QML>
 +import QtQuick 2.8; import QtQuick.Controls 2.2; import QtQuick.Layouts 1.3;
 +import my.class.Calc 1.0
  
 +ApplicationWindow
 +{
 +    title: "Factorial Calc"; width: 250; height: 80;
 +    visible: true
 +    Calculation
 +    {
 +        id: calc
 +    }
 +    ColumnLayout
 +    {
 +        anchors.fill: parent
 +        RowLayout // Первый подход, с использованием метода
 +        {
 +            SpinBox
 +            {
 +                id: sbx
 +                value: 0
 +            }
 +            Text
 +            {
 +                text: "Result: "+ calc.factorial(sbx.value)
 +            }
 +        }
 +        RowLayout // Второй подход, с использованием свойств
 +        {
 +            SpinBox
 +            {
 +                value: 0
 +                onValueChanged: calc.input= value
 +            }
 +            Text
 +            {
 +                text: "Result: "+ calc.result
 +            }
 +        }
 +    }
 +}
 </code> </code>
-</details> 
  
 +
 +**Альтернативный подход** с использованием сигналов
 +<code QML>
 +import QtQuick 2.8; import QtQuick.Controls 2.2; import QtQuick.Layouts 1.3;
 +import my.class.Calc 1.0
 +
 +ApplicationWindow
 +{
 +    title: "Factorial Calc"; width: 250; height: 80;
 +    visible: true
 +    Calculatoin
 +    {
 +        input: sbx.value
 +        onResultValueChanged: txt.text= "Result: "+ result
 +    }
 +    RowLayout
 +    {
 +        SpinBox
 +        {
 +            id: sbx
 +            value: 0
 +        }
 +        Text
 +        {
 +            id: txt
 +        }
 +    }
 +}
 +</code>
 +</details>
  
    
 === Реализация визуальных элементов QML на C++ === === Реализация визуальных элементов QML на C++ ===
 ---- ----
 +Все базовые **элементы QML** (такие как Rectangle или Text), **реализованы на C++** (QQuickRectangle, QQuickText), унаследованы они от **QQuickItem**, для собственной реализации нужно наследовать этот класс, но есть спец подготовленный для этого- **QQuickPaintedItem**, он уже унаследован.\\
  
 <details> <details>
-<summary>:!: Пример: </summary> +<summary>:!: Пример: Собственный элемент, эллипс</summary> 
-<code QML>+**Ellipse.h** 
 +<code cpp-qt> 
 +#ifndef ELLIPSE_H 
 +#define ELLIPSE_H
  
 +#include <QQuickPaintedItem>
 +
 +class QPainter;
 +
 +class Ellipse: public QQuickPaintedItem
 +{
 +    Q_OBJECT
 +
 +private:
 +    Q_PROPERTY(QColor color WRITE setColorValue
 +                            READ colorValue)
 +    QColor m_color;
 +
 +public:
 +    Ellipse(QQuickItem *parent= nullptr);
 +    // Отвечает рисование элемента, вызывается при обновлении
 +    void paint(QPainter *ppainter);
 +    QColor colorValue() const;
 +    void setColorValue(const QColor&);
 +};
 +
 +#endif // ELLIPSE_H
 </code> </code>
-</details> 
  
  
 +**Ellipse.hpp**
 +<code cpp-qt>
 +#include "ellipse.h"
 +#include <QPainter>
  
-  +Ellipse::Ellipse(QQuickItem *parent): QQuickPaintedItem(parent), m_color(Qt::black) 
-=== Класс QQuickImageProvider ==== +{ 
-----+}
  
 +void Ellipse::paint(QPainter *ppainter)
 +{
 +    ppainter->setRenderHint(QPainter::Antialiasing, true);
 +    ppainter->setBrush(QBrush(this->colorValue()));
 +    ppainter->setPen(Qt::NoPen);
 +    ppainter->drawEllipse(boundingRect());
 +}
  
-<details+QColor Ellipse::colorValue() const 
-<summary>:!: Пример: </summary>+
 +    return this->m_color; 
 +
 + 
 +void Ellipse::setColorValue(const QColor &vCol) 
 +
 +    this->m_color= vCol; 
 +
 +</code> 
 + 
 + 
 +**main.hpp** 
 +<code cpp-qt> 
 +#include <QGuiApplication> 
 +#include <QQmlApplicationEngine> 
 +#include "ellipse.h" 
 + 
 +int main(int argc, char** argv) 
 +
 +    QGuiApplication app(argc, argv); 
 +    qmlRegisterType<Ellipse>("my.class.Ellipse", 1, 0, "Ellipse"); 
 +    QQmlApplicationEngine engine; 
 +    engine.load(QUrl("qrc:/main.qml")); 
 + 
 +    return app.exec(); 
 +
 +</code> 
 + 
 + 
 +**main.qml**
 <code QML> <code QML>
 +import QtQuick 2.8; import QtQuick.Controls 2.2
 +import my.class.Ellipse 1.0
  
 +ApplicationWindow
 +{
 +    title: "Paint Element"; width: 200; height: 100;
 +    visible: true
 +    Ellipse
 +    {
 +        anchors.fill: parent
 +        color: "blue"
 +    }
 +}
 </code> </code>
 </details> </details>
  
 + 
 +=== Класс QQuickImageProvider ====
 +----
 +Этот класс является неким объектом, который возвращает запрашиваемое изображение (QImage либо QPixmap), запрашивается оно из QML по имени файла (либо какой-нибудь условный идентификатор), зарегистрированный ImageProvider типа папка, а идентификатор имя файла.\\
 +Т.к. ImageProvider возвращает (методом request) изображение в как таковом виде (тип данных image/pixmap), его можно всячески модифицировать перед отправкой, или даже вовсе создать в этом методе, либо организовать некую логику, на основании переданных данных например..\\
  
 <details> <details>
-<summary>:!: Пример: </summary>+<summary>:!: Пример: Яркость изображения</summary> 
 + 
 +**ImageProvider.h** 
 +<code cpp-qt> 
 +#ifndef IMAGEPROVIDER_H 
 +#define IMAGEPROVIDER_H 
 +#include <QQuickImageProvider> 
 +#include <QObject> 
 +#include <QImage> 
 + 
 +class ImageProvider: public QQuickImageProvider 
 +
 +private: 
 +    QImage brightness(const QImage &imgOrig, int n); 
 + 
 +public: 
 +    ImageProvider(); 
 +    QImage requestImage(const QString&, QSize*, const QSize&); 
 +}; 
 + 
 +#endif // IMAGEPROVIDER_H 
 +</code> 
 + 
 + 
 +**ImageProvider.hpp** 
 +<code cpp-qt> 
 +#include "imageprovider.h" 
 + 
 +ImageProvider::ImageProvider(): QQuickImageProvider(QQuickImageProvider::Image) 
 +
 +
 + 
 +QImage ImageProvider::brightness(const QImage &imgOrig, int n) 
 +
 +    QImage imgTemp= imgOrig; 
 +    qint32 nHeigt= imgTemp.height(); 
 +    qint32 nWidth= imgTemp.width(); 
 + 
 +    for(qint32 y= 0; y < nHeigt; ++y) 
 +    { 
 +        QRgb *tempLine= reinterpret_cast<QRgb*>(imgTemp.scanLine(y)); 
 +        for(qint32 x= 0; x < nWidth; ++x) 
 +        { 
 +            int r= qRed(*tempLine) + n; 
 +            int g= qGreen(*tempLine) + n; 
 +            int b= qBlue(*tempLine) + n; 
 +            int a= qAlpha(*tempLine); 
 + 
 +            *tempLine++ = qRgba(r > 255 ? 255 : r < 0 ? 0:r, 
 +                                g > 255 ? 255 : g < 0 ? 0:g, 
 +                                b > 255 ? 255 : b < 0 ? 0:b, 
 +                                a); 
 +        } 
 +    } 
 +    return imgTemp; 
 +
 + 
 +QImage ImageProvider::requestImage(const QString &strId, QSize *ps, const QSize &requestedSize) 
 +
 +    QStringList lst= strId.split(";"); 
 +    bool bOk= false; 
 +    int nBrightness= lst.last().toInt(&bOk); 
 +    QImage img= brightness(QImage(":/"+ lst.first()), nBrightness); 
 + 
 +    if(ps) 
 +        *ps= img.size(); 
 + 
 +    return img; 
 +
 +</code> 
 + 
 + 
 +**main.hpp** 
 +<code cpp-qt> 
 +#include <QGuiApplication> 
 +#include <QQmlApplicationEngine> 
 +#include "imageprovider.h" 
 + 
 +int main(int argc, char** argv) 
 +
 +    QGuiApplication app(argc, argv); 
 +    QQmlApplicationEngine engine; 
 +    engine.addImageProvider(QLatin1String("brightness"), new ImageProvider); 
 +    engine.load(QUrl("qrc:/main.qml")); 
 + 
 +    return app.exec(); 
 +
 +</code> 
 + 
 + 
 +**main.qml**
 <code QML> <code QML>
 +import QtQuick 2.8; import QtQuick.Controls 2.2
  
 +ApplicationWindow
 +{
 +    title: "Brightness"; width: controls.width; height: controls.height;
 +    visible: true
 +    Column
 +    {
 +        id: controls
 +        Image
 +        {
 +            id: img
 +            source: "image://brightness/11.jpg;"+ sld.brightnessValue
 +        }
 +        Slider
 +        {
 +            id: sld
 +            width: img.width
 +            value: 0.75
 +            stepSize: 0.01
 +            property int brightnessValue: (value * 255 -127)
 +        }
 +        Text
 +        {
 +            width: img.width
 +            text: "<h1>Brightness: "+ sld.brightnessValue+ "</h1>"
 +        }
 +    }
 +}
 </code> </code>
 </details> </details>
- 
develop/qt/quick3.1630429213.txt.gz · Последнее изменение: 2021/08/31 17:00 — admin