Terabaytus
Terabaytus28 лютого 2018 р. 07:41

Как связать QML и С++

QML, qml

Добрый день, подскажите уже какой день бьюсь с этим вопросом.  Работаю в QT5.10

Есть написанный на javaskript переключатель

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick 2.6
import QtQuick.Controls 2.1


Window {
    visible: true
    width: 200
    height: 50
    maximumHeight: height
    maximumWidth: width
    minimumHeight: height
    minimumWidth: width
    title: qsTr("")




    SwitchDelegate {
                id: control
                text: qsTr("          ")
                checked: false

                contentItem: Text {
                    rightPadding: control.indicator.width + control.spacing
                    text: control.text
                    font: control.font
                    opacity: enabled ? 1.0 : 0.3
                    color: control.down ? "#17a81a" : "#21be2b"
                    elide: Text.ElideRight
                    verticalAlignment: Text.AlignVCenter
                }

                indicator: Rectangle {
                    implicitWidth: 48
                    implicitHeight: 26
                    x: control.width - width - control.rightPadding
                    y: parent.height / 2 - height / 2
                    radius: 13
                    color: control.checked ? "#17a81a" : "transparent"
                    border.color: control.checked ? "#17a81a" : "#cccccc"

                    Rectangle {
                        x: control.checked ? parent.width - width : 0
                        width: 26
                        height: 26
                        radius: 13
                        color: control.down ? "#cccccc" : "#ffffff"
                        border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999"
                    }
                }

                background: Rectangle {
                    implicitWidth: 100
                    implicitHeight: 40
                    visible: control.down || control.highlighted
                    color: control.down ? "#bdbebf" : "#eeeeee"
                }
            }
}
как мне теперь получить сигнал о его состоянии влючён/выключен и вторым этапом включить его из кода  и так же выключить  в своём классе backend.cpp знаю что через SLOT и SIGNAL, но немогу понять.
Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

9
Evgenii Legotckoi
  • 28 лютого 2018 р. 15:47

Добрый день.

Вообще делегаты используются для создания внешнего вида элемента в списке (ListView), например. Но никак не самостоятельные переключатели.
Это первый момент. Поэтому надеюсь, что Вы не будете его использовать как самостоятельный объект.

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

Это будет выглядеть так.

signal isChecked(var checked)

onClicked: {
    isChecked(checked)
}
Либо уже сразу делать что-то ядром, как было показано в том уроке.
onClicked: {
    appCore.receiveFromQml(checked)
}
Просто придётся добавить аргумент в слот, например, так
void AppCore::receiveFromQml(bool checked);
    Terabaytus
    • 01 березня 2018 р. 03:02

    Можно по шагам всё пройти я добавил делегат в список (ListView) как мне теперь к нему обратиться- вызвать его в коде С++ ?

     ListView {
            id: listView
            x: 0
            y: 0
            width: 200
            height: 50
            SwitchDelegate {
                id: control
                x: 0
                y: 0
                width: 200
                height: 50
                text: qsTr("Сервер           ")
                checked: false
    
                contentItem: Text {
                    rightPadding: control.indicator.width + control.spacing
                    text: control.text
                    font: control.font
                    opacity: enabled ? 1.0 : 0.3
                    color: control.down ? "#17a81a" : "#21be2b"
                    elide: Text.ElideRight
                    verticalAlignment: Text.AlignVCenter
                }
    
                indicator: Rectangle {
                    implicitWidth: 48
                    implicitHeight: 26
                    x: control.width - width - control.rightPadding
                    y: parent.height / 2 - height / 2
                    radius: 13
                    color: control.checked ? "#17a81a" : "transparent"
                    border.color: control.checked ? "#17a81a" : "#cccccc"
    
                    Rectangle {
                        x: control.checked ? parent.width - width : 0
                        width: 26
                        height: 26
                        radius: 13
                        color: control.down ? "#cccccc" : "#ffffff"
                        border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999"
                    }
                }
    
                background: Rectangle {
                    implicitWidth: 100
                    implicitHeight: 40
                    visible: control.down || control.highlighted
                    color: control.down ? "#bdbebf" : "#eeeeee"
                }
            }
    
    
        }
      Evgenii Legotckoi
      • 01 березня 2018 р. 16:02

      Я, возможно, не так ясно выразился.

      Сам по себе SwitchDelegate является лишь делегатом внешнего вида для списка объектов например, которые повторяются в ListView, например. Делегаты используются для стилизации частей приложения, но никак не самостоятельные объекты.

      Вам Нужно использовать не SwitchDelegate, а просто Switch. А обращаться так, как я Вам показал в предыдущем сообщении. В статье, по которой Вы задали вопрос, есть пример с регистрацией бэкенда в контексте QML. То есть можете именно таким образом и обратиться к это объекту. То есть по событию onClicked проверить состояние и закинуть его в бекенд.
        Terabaytus
        • 02 березня 2018 р. 08:04
        • (відредаговано)

        Как Вы и сказали,  сменил delegat на swich  и переключатель ожил при переводе тумблера в консоль выдаёт

        qrc:/main.qml:75:29 : Unable to assign [undefined] to bool

        ругается вот на этот участок кода

        background: Rectangle {
                           implicitWidth: 100
                           implicitHeight: 40
                           visible: control.down || control.highlighted
                           color: control.down ? "#bdbebf" : "#eeeeee"
                       }


        но в начале выдаёт

        qrc:/main.qml:20:5 : QML Connections: Cannot assign to non-existent property "onClicked"

        взгляните пожалуйста на код что я не так делаю

        QML

        Window {
            visible: true
            width: 200
            height: 50
            maximumHeight: height
            maximumWidth: width
            minimumHeight: height
            minimumWidth: width
            title: qsTr("Hi")
        
            /* С помощью объекта Connections
             * Устанавливаем соединение с классом ядра приложения
             * */
            Connections {
                target: backend  // Указываем целевое соединение
        
        
        
                onSendToQml: {
        
                    console.log(count); // выводит в консоль
                }
        
                onClicked: {
                    backend.receiveFromQml(control);
                }
        
         }
                 Switch {
                       id: control
                       x: 0
                       y: 0
                       width: 200
                       height: 50
                       text: qsTr("Hi           ")
                       checked: false
                       contentItem: Text {
                           rightPadding: control.indicator.width + control.spacing
                           text: control.text
                           font: control.font
                           opacity: enabled ? 1.0 : 0.3
                           color: control.down ? "#17a81a" : "#21be2b"
                           elide: Text.ElideRight
                           verticalAlignment: Text.AlignVCenter
                       }
        
                       indicator: Rectangle {
                           implicitWidth: 48
                           implicitHeight: 26
                           x: control.width - width - control.rightPadding
                           y: parent.height / 2 - height / 2
                           radius: 13
                           color: control.checked ? "#17a81a" : "transparent"
                           border.color: control.checked ? "#17a81a" : "#cccccc"
        
                           Rectangle {
                               x: control.checked ? parent.width - width : 0
                               width: 26
                               height: 26
                               radius: 13
                               color: control.down ? "#cccccc" : "#ffffff"
                               border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999"
                           }
                       }
        
                       background: Rectangle {
                           implicitWidth: 100
                           implicitHeight: 40
                           visible: control.down || control.highlighted
                           color: control.down ? "#bdbebf" : "#eeeeee"
                       }
                   }
        
               }
        main.cpp

        int main(int argc, char *argv[])
        {
        #if defined(Q_OS_WIN)
            QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        #endif
        
            QGuiApplication app(argc, argv);
        
          
            QQmlApplicationEngine engine;// Создаём движок qml
        
            Backend backend; // Создаём ядро приложения
            QQmlContext *context = engine.rootContext();    // Создаём корневой контекст
        
            /* Загружаем объект в контекст для установки соединения,
             * а также определяем имя, по которому будет происходить соединение
             * */
            context->setContextProperty("backend", &backend);
        
            engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
            if (engine.rootObjects().isEmpty())
                return -1;
        
            return app.exec();
        }
        backend.cpp

        Backend::Backend(QObject *parent) : QObject(parent)
        {
           count =0;
        }
        
        void Backend::receiveFromQml(bool control)
        {
          std::cout << control << std::endl;
            count++;
            emit sendToQml(count);//отправляем данные в qml
        }
        backend.h

        class Backend : public QObject
        {
            Q_OBJECT
            //Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)
        
        public:
            explicit Backend(QObject *parent = nullptr);
        
        signals:
            // Сигнал для передачи данных в qml-интерфейс
            void sendToQml(int count);
        
        public slots:
            // Слот для приёма данных из qml-интерфейса
            void receiveFromQml(bool control);
        
        private:
            // Данные, которыми будем оперировать
            int count;
        };
        
        
        #endif // BACKEND_H
        
        

          Evgenii Legotckoi
          • 02 березня 2018 р. 08:10
          • (відредаговано)
          • Відповідь була позначена як рішення.

          У Switch не свойства highlighted, поэтому тот участок кода нужно переписать так

          background: Rectangle {
              implicitWidth: 100
              implicitHeight: 40
              visible: control.down
              color: control.down ? "#bdbebf" : "#eeeeee"
          }
          А Сигнал onClicked не туда поместили, его нужно было поместить в Switch, поскольку Switch имеет сигнал clicked, а не ваш Backend класс, к которому Вы подключаетесь через тип Connections

          Switch {
              onClicked: {
                  backend.receiveFromQml(control);
              }
          }
            Terabaytus
            • 31 травня 2018 р. 04:15
            • (відредаговано)

            Добрый день, обращаюсь к вам с вопросом на туже тему.


            У меня пропала связь QML слоя с С++ в лог выводиться:

            TypeError: Property 'setBackend' of object BackEnd(0x7fff41680340) is not a function

            main.qml

            import QtQuick 2.9
            import QtQuick.Window 2.2
            import QtQuick 2.6
            import QtQuick.Controls 1.4
            import QtQuick.Controls 2.1
            
            Window {
                id: window
                visible: true
                width: 300
                height: 310
                maximumHeight: height
                maximumWidth: width
                minimumHeight: height
                minimumWidth: width
                title: qsTr("ServerARS")
            
                /* С помощью объекта Connections
                 * Устанавливаем соединение с классом ядра приложения
                 * */
                Connections {
            
                    target: backend  
            
            
            
                    onSendToQml: {
            console.log(countitch { id: control x: 0 y: 0 width: 300 height: 50 text: qsTr("") checked: false onClicked: { backend.setBackend(control); console.log("count"); } contentItem: Text { rightPadding: control.indicator.width + control.spacing text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } indicator: Rectangle { implicitWidth: 48 implicitHeight: 26 x: control.width - width - control.rightPadding y: parent.height / 2 - height / 2 radius: 13 color: control.checked ? "#17a81a" : "transparent" border.color: control.checked ? "#17a81a" : "#cccccc" Rectangle { x: control.checked ? parent.width - width : 0 width: 26 height: 26 radius: 13 color: control.down ? "#cccccc" : "#ffffff" border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999" } } background: Rectangle { implicitWidth: 100 implicitHeight: 40 visible: control.down /*|| control.highlighted*/ color: control.down ? "#bdbebf" : "#eeeeee" } } }
            main.cpp

            #include <QGuiApplication>
            #include <QQmlApplicationEngine>
            #include <QQmlContext>
            #include "backend.h"
            
            int main(int argc, char *argv[])
            {
                QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
            
                QGuiApplication app(argc, argv);
            
                QQmlApplicationEngine engine;// Создаём движок qml
            
                BackEnd backend; // Создаём ядро приложения
            
                QQmlContext *context = engine.rootContext(); // Создаём корневой контекст, загружаем объект в контекст для установки соединения
            
                context->setContextProperty("backend", &backend); //определяем имя, по которому будет происходить соединение
            
                engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); // загружаем в него исходник qml
                if (engine.rootObjects().isEmpty())
                    return -1;
            
                return app.exec();
            }
            
            backend.h

            #ifndef BACKEND_H
            #define BACKEND_H
            
            #include <QObject>
            #include <QString>
            
            class BackEnd : public QObject
            {
                Q_OBJECT
            
            public:
                explicit BackEnd(QObject *parent = 0);
             
            
            signals: 
            
                void sendToQml(int count);
            
            private slots: 
                void setBackend(bool control);
            
            public: 
            
            };
            #endif // BACKEND_H
            backend.cpp

            #include "backend.h"
            #include <iostream>
            
            BackEnd::BackEnd(QObject *parent) : QObject(parent)
            {
               
                count =0;
            
            
            }
            
            
            void BackEnd::setBackend(bool control) 
            {
               std::cout << control << std::endl ;
            
                 count++       
            emit sendToQml(count); std::cout << count << std::endl ; }
            В чём может быть дело, ещё как мне кажется у меня не инициализируются переменная count QT5.11 подсвечивает её красным.
              Evgenii Legotckoi
              • 31 травня 2018 р. 04:20

              Добрый день!

              Проблема скорее всего в том, что слот setBackend объявлен приватным. переместите его в public slots секцию
                Terabaytus
                • 31 травня 2018 р. 04:30

                Спасибо, действительно всё так. Я столько времени на это потратил (

                  Evgenii Legotckoi
                  • 31 травня 2018 р. 04:31

                  случается

                    Коментарі

                    Only authorized users can post comments.
                    Please, Log in or Sign up
                    sf

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

                    • Результат:90бали,
                    • Рейтинг балів8
                    МВ

                    Qt - Тест 001. Сигналы и слоты

                    • Результат:68бали,
                    • Рейтинг балів-1
                    ЛС

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

                    • Результат:53бали,
                    • Рейтинг балів-4
                    Останні коментарі
                    A
                    ALO1ZE19 жовтня 2024 р. 08:19
                    Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                    ИМ
                    Игорь Максимов05 жовтня 2024 р. 07:51
                    Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                    d
                    dblas505 липня 2024 р. 11:02
                    QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                    k
                    kmssr08 лютого 2024 р. 18:43
                    Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                    АК
                    Анатолий Кононенко05 лютого 2024 р. 01:50
                    Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                    Тепер обговоріть на форумі
                    J
                    JacobFib17 жовтня 2024 р. 03:27
                    добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
                    ИМ
                    Игорь Максимов03 жовтня 2024 р. 04:05
                    Реализация навигации по разделам Спасибо Евгений!
                    JW
                    Jhon Wick01 жовтня 2024 р. 15:52
                    Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
                    КГ
                    Кирилл Гусарев27 вересня 2024 р. 09:09
                    Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
                    F
                    Fynjy22 липня 2024 р. 04:15
                    при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

                    Слідкуйте за нами в соціальних мережах