Terabaytus
Terabaytus28. Februar 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
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

9
Evgenii Legotckoi
  • 28. Februar 2018 15:47

Добрый день.

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

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

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

signal isChecked(var checked)

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

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

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

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

        Как Вы и сказали,  сменил 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. März 2018 08:10
          • (bearbeitet)
          • Die Antwort wurde als Lösung markiert.

          У 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. Mai 2018 04:15
            • (bearbeitet)

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


            У меня пропала связь 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. Mai 2018 04:20

              Добрый день!

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

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

                  Evgenii Legotckoi
                  • 31. Mai 2018 04:31

                  случается

                    Kommentare

                    Nur autorisierte Benutzer können Kommentare posten.
                    Bitte Anmelden oder Registrieren
                    Letzte Kommentare
                    A
                    ALO1ZE19. Oktober 2024 18:19
                    Fb3-Dateileser auf Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                    ИМ
                    Игорь Максимов5. Oktober 2024 17:51
                    Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                    d
                    dblas55. Juli 2024 21:02
                    QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                    k
                    kmssr9. Februar 2024 05:43
                    Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                    Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                    Jetzt im Forum diskutieren
                    J
                    JacobFib17. Oktober 2024 13:27
                    добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
                    JW
                    Jhon Wick2. Oktober 2024 01: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. September 2024 19:09
                    Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
                    F
                    Fynjy22. Juli 2024 14:15
                    при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

                    Folgen Sie uns in sozialen Netzwerken