Terabaytus
Terabaytus28 февраля 2018 г. 7: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
    • 1 марта 2018 г. 3: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
      • 1 марта 2018 г. 16:02

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

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

      Вам Нужно использовать не SwitchDelegate, а просто Switch. А обращаться так, как я Вам показал в предыдущем сообщении. В статье, по которой Вы задали вопрос, есть пример с регистрацией бэкенда в контексте QML. То есть можете именно таким образом и обратиться к это объекту. То есть по событию onClicked проверить состояние и закинуть его в бекенд.
        Terabaytus
        • 2 марта 2018 г. 8: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
          • 2 марта 2018 г. 8: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 г. 4: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 г. 4:20

              Добрый день!

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

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

                  Evgenii Legotckoi
                  • 31 мая 2018 г. 4:31

                  случается

                    Комментарии

                    Только авторизованные пользователи могут публиковать комментарии.
                    Пожалуйста, авторизуйтесь или зарегистрируйтесь
                    г
                    • ги
                    • 23 апреля 2024 г. 15:51

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

                    • Результат:41баллов,
                    • Очки рейтинга-8
                    l
                    • laei
                    • 23 апреля 2024 г. 9:19

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

                    • Результат:10баллов,
                    • Очки рейтинга-10
                    l
                    • laei
                    • 23 апреля 2024 г. 9:17

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

                    • Результат:50баллов,
                    • Очки рейтинга-4
                    Последние комментарии
                    k
                    kmssr8 февраля 2024 г. 18:43
                    Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                    АК
                    Анатолий Кононенко5 февраля 2024 г. 1:50
                    Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                    EVA
                    EVA25 декабря 2023 г. 10:30
                    Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
                    J
                    JonnyJo25 декабря 2023 г. 8:38
                    Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
                    G
                    Gvozdik18 декабря 2023 г. 21:01
                    Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
                    Сейчас обсуждают на форуме
                    G
                    Gar22 апреля 2024 г. 5:46
                    Clipboard Как скопировать окно целиком в clipb?
                    DA
                    Dr Gangil Academics20 апреля 2024 г. 7:45
                    Unlock Your Aesthetic Potential: Explore MSC in Facial Aesthetics and Cosmetology in India Embark on a transformative journey with an msc in facial aesthetics and cosmetology in india . Delve into the intricate world of beauty and rejuvenation, guided by expert faculty and …
                    a
                    a_vlasov14 апреля 2024 г. 6:41
                    Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
                    Павел Дорофеев
                    Павел Дорофеев14 апреля 2024 г. 2:35
                    QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
                    f
                    fastrex4 апреля 2024 г. 4:47
                    Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

                    Следите за нами в социальных сетях