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

Добрый день.

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

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

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

signal isChecked(var checked)

onClicked: {
    isChecked(checked)
}
Либо уже сразу делать что-то ядром, как было показано в том уроке.
onClicked: {
    appCore.receiveFromQml(checked)
}
Просто придётся добавить аргумент в слот, например, так
void AppCore::receiveFromQml(bool checked);
    Terabaytus
    • 1 марта 2018 г. 14: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
      • 2 марта 2018 г. 3:02

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

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

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

              Добрый день!

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

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

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

                  случается

                    Комментарии

                    Только авторизованные пользователи могут публиковать комментарии.
                    Пожалуйста, авторизуйтесь или зарегистрируйтесь
                    Ua

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

                    • Результат:84баллов,
                    • Очки рейтинга4
                    Ua

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

                    • Результат:42баллов,
                    • Очки рейтинга-8
                    ОК

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

                    • Результат:47баллов,
                    • Очки рейтинга-6
                    Последние комментарии
                    ИМ
                    Игорь Максимов22 ноября 2024 г. 21:51
                    Django - Урок 017. Кастомизированная страница авторизации на Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                    Evgenii Legotckoi
                    Evgenii Legotckoi31 октября 2024 г. 23:37
                    Django - Урок 064. Как написать расширение для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                    A
                    ALO1ZE19 октября 2024 г. 17:19
                    Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                    ИМ
                    Игорь Максимов5 октября 2024 г. 16:51
                    Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                    d
                    dblas55 июля 2024 г. 20:02
                    QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                    Сейчас обсуждают на форуме
                    f
                    firstlunoxod15 февраля 2025 г. 13:46
                    Рисование на QGraphicsScene при зажатой кнопке мыши Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
                    Дмитрий
                    Дмитрий3 февраля 2025 г. 16:24
                    Создание deb-пакета. Как создать ярлык на рабочем столе после установки собственного deb-пакета? Всем привет. Сделал свой deb-пакет с программой. Всё устанавливается и работает. Ставлю по пути /usr/bin/my_application. Как для пользователя при установке пакета сразу создать ярлык на раб…
                    NW
                    Nayo Wai30 января 2025 г. 19:22
                    не запускается компьютер!!! Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
                    n
                    nkly3 января 2025 г. 12:52
                    Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
                    M
                    Marsel17 августа 2023 г. 0:26
                    OAuth2.0 через VK, получение email Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.

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