H
Hunter17626313 января 2017 г. 21:00

Отправка сигнала QML

Signal, Slot, Qt, QML

Доброго времени суток. Я в QT да и в QML новичок, потому прошу помощи. Столкнулся вот с какой загвоздкой, нужно чтоб при отправке сигнала в QML, окно авторизации скрывалось и открывалось другое. Делал по 3 и 20 урокам, с некоторыми изменениями.В общем при отправке сигнала ничего не происходит, не могу понять в чем проблема.

login.cpp(место где происходит отправка сигнала)
 if (count==1){
        // ("username and password is correct");
          emit sendToQml();

     }
login.h
#define LOGIN_H

#include <QSqlQuery>
#include <QObject>
#include <QVariant>

class CLogin : public QObject
{
    Q_OBJECT
public:
    explicit CLogin(QObject *parent = 0);

signals:
    void sendToQml();
public slots:
    void loginSlot();
private:
    int count;

};

#endif // LOGIN_H

main.qml(часть описания окна авторизации)
ApplicationWindow {
    id:logwindow
    visible: true
        width: 540
        height: 380
        title: qsTr("Окно авторизации")

        Material.theme: Material.Light
        Material.primary: Material.Cyan
        Material.accent: Material.Blue

        signal qmlSignal()


        Connections {
               target: clogin

              onSendToQml: {
                       logwindow.hide();
                        window.show();
               }
        }
Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

4
Evgenii Legotckoi
  • 4 января 2017 г. 0:38

Добрый день

На первый взгляд всё сделано правильно. Но я не могу утверждать этого до конца, поскольку Вы не привели код из main.cpp файла. А также я не вижу здесь кода, в котором переменная count обнуляется. Если Вы её не обнуляли, то там может быть мусор. А соответственно единицу в этой переменной можете получить очень не скоро.

Вот мой рабочий пример:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "login.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    QQmlContext* context = engine.rootContext();
    Login login;
    context->setContextProperty("login", &login);
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));

    return app.exec();
}

login.h

#ifndef LOGIN_H
#define LOGIN_H

#include <QObject>

class Login : public QObject
{
    Q_OBJECT
public:
    explicit Login(QObject *parent = 0);

signals:
    void sendToQml();
public slots:
    void loginSlot();
private:
    int count;
};

#endif // LOGIN_H

login.cpp

#include "login.h"

Login::Login(QObject *parent) : QObject(parent), count(0)
{

}

void Login::loginSlot()
{
    count++;
    if (count == 5)
    {
        emit sendToQml();
    }
}

main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Button {
        text: "Hello"

        onClicked: {
            login.loginSlot()
        }
    }

    Connections {
        target: login
        onSendToQml: {
            console.log("HELLO")
        }
    }
}
    H
    • 4 января 2017 г. 9:53

    Спасибо за приведеный вами выше пример.Но мне нужна немного другая реализация, я хочу чтоб происходило только отправление сигнала, при котором будет происходит скрытие/открытие окон.Прошу прощения что сразу не привел полный код, не хотел загромождать, пока что проблему не удалось решить,по прежнему не скрывается окно авторизации и не открывается новое,хотя по условию count==1 заходит, прилагаю весь код.В чем может быть проблема?

    main.qml

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.0
    import QtQuick.Controls.Material 2.0
    import QtQuick.Dialogs 1.2
    import QtQuick.Window 2.0
    
    ApplicationWindow {
        id:logwindow
        visible: true
            width: 540
            height: 380
            title: qsTr("Окно авторизации")
    
            Material.theme: Material.Light
            Material.primary: Material.Cyan
            Material.accent: Material.Blue
    
            signal qmlSignal()
    
    
            Connections {
                   target: clogin
    
                  onSendToQml: {
                           logwindow.hide();
                            window.show();
                   }
            }
    
    
            Column {
                spacing: 10
                anchors.centerIn: parent
    
                TextField {
                    id: login
                    objectName: "login"
                    placeholderText: "Введите Логин"
                    width: 250
    
                }
    
                TextField {
                    id: password
                    objectName: "password"
                    placeholderText: "Введите Пароль"
                    width: 250
                }
    
                Button {
                    id:enter
                    text: qsTr("Войти")
                    width: 250
                    onClicked:{
                        qmlSignal()
                       //logwindow.hide()
    
                    }
    
    
                }
    
                Button {
                    id: reg
                    text: qsTr("Регистрация")
                    width: 250
                }
    
    
            }
            Window {
                id:window
                 title: qsTr("Окно вторичное")
                visible: false
                    width: 540
                    height: 380
            }
    
    
    }
    
    

    main.cpp

    #include <QQmlApplicationEngine>
    #include <connect.h>
    #include <clogin.h>
    #include <QDebug>
    #include <QQmlContext>
    
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
        CLogin clogin;
        QQmlContext *context = engine.rootContext();
        context->setContextProperty("clogin",&clogin);
        engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    
        QObject* root = engine.rootObjects()[0];
    
           CLogin *login= new CLogin(root);
           Connect con;
           con.open();
    
    
               QObject::connect(root, SIGNAL(qmlSignal()),
                                login, SLOT(loginSlot()));
    
    
        return app.exec();
    }
    

    clogin.cpp

    #include "clogin.h"
    #include <QString>
    #include <QObject>
    #include <iostream>
    #include <QDebug>
    
    using namespace std;
    
    CLogin::CLogin(QObject *parent) : QObject(parent)
    {
    
    }
    
    void CLogin::loginSlot() {
    
    //Найдем строки ввода
    QObject* field1 = this->parent()->findChild<QObject*>("login");
    QObject* field2 = this->parent()->findChild<QObject*>("password");
    //Найдем поле вывода
    
    //Считаем информацию со строк ввода через свойство text
    QString str1=(field1->property("text")).toString();
    QString str2=(field2->property("text")).toString();
    
    
    QSqlQuery qry;
    
    
    if(qry.exec("select * from clients where client_login='"+str1+"' and client_password='"+str2+"'")){
        count =0;
         while(qry.next())
         {
             count++;
         }
    
         if (count==1){
            // ("username and password is correct");
              emit sendToQml();
    
         }
    
    
         if (count>1)
    
            // ("Duplicate username and password");
         if (count<1)
    
            // ("username and password is not correct");
         if(!count<1||!count>1)
         {
             //открыть окно
         }
    
    
    }
    
    }
    

    clogin.h

    #include <QSqlQuery>
    #include <QObject>
    #include <QVariant>
    
    class CLogin : public QObject
    {
        Q_OBJECT
    public:
        explicit CLogin(QObject *parent = 0);
    
    signals:
        void sendToQml();
    public slots:
        void loginSlot();
    private:
        int count;
    
    };
    
      Evgenii Legotckoi
      • 5 января 2017 г. 7:11
      • Ответ был помечен как решение.

      Вы регистрируете в движке QML в качестве свойства один объект clogin :

      CLogin clogin;
      QQmlContext *context = engine.rootContext();
      context->setContextProperty("clogin",&clogin);
      

      И настраиваете на него Connections

      Connections {
             target: clogin
      
            onSendToQml: {
                     logwindow.hide();
                      window.show();
             }
      }
      

      А сигнал на проверку данных по попытке подключения навешиваете на совершенно другой объект того же самого класса. Поэтому clogin просто простаивает, и не отправляет сигнал в QML, поскольку вы заставляете проверять подключения совершенно другой объект, сигналы которого не обрабатываются в QML.

      CLogin *login= new CLogin(root);
      QObject::connect(root, SIGNAL(qmlSignal()), login, SLOT(loginSlot()));
      
      Так что используйте только один объект, который будет принимать сигнал на попытку входа, обработку данных и будет выдавать сигнал, по которому вы уже переключите окна.

      То есть объедините login и clogin , используйте только один объект

        H
        • 5 января 2017 г. 8:22

        Спасибо Вам большое, все заработало. Я б не догадался). Мне казалось что Conection создал, а дальше делай что хочешь)). Еще раз спасибо большое.

          Комментарии

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

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

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

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

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

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

          • Результат:91баллов,
          • Очки рейтинга8
          Последние комментарии
          k
          kmssr9 февраля 2024 г. 5:43
          Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
          АК
          Анатолий Кононенко5 февраля 2024 г. 12:50
          Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
          EVA
          EVA25 декабря 2023 г. 21:30
          Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
          J
          JonnyJo25 декабря 2023 г. 19:38
          Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
          G
          Gvozdik19 декабря 2023 г. 8:01
          Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
          Сейчас обсуждают на форуме
          P
          Pisych27 февраля 2023 г. 15:04
          Как получить в массив значения из связанной модели? Спасибо, разобрался:))
          AC
          Alexandru Codreanu19 января 2024 г. 22:57
          QML Обнулить значения SpinBox Доброго времени суток, не могу разобраться с обнулением значение SpinBox находящего в делегате. import QtQuickimport QtQuick.ControlsWindow { width: 640 height: 480 visible: tr…
          BlinCT
          BlinCT27 декабря 2023 г. 19:57
          Растягивать Image на парент по высоте Ну и само собою дял включения scrollbar надо чтобы был Flickable. Так что выходит как то так Flickable{ id: root anchors.fill: parent clip: true property url linkFile p…
          Дмитрий
          Дмитрий10 января 2024 г. 15:18
          Qt Creator загружает всю оперативную память Проблема решена. Удалось разобраться с помощью утилиты strace. Запустил ее: strace ./qtcreator Начал выводиться весь лог работы креатора. В один момент он начал считывать фай…
          Evgenii Legotckoi
          Evgenii Legotckoi12 декабря 2023 г. 17:48
          Побуквенное сравнение двух строк Добрый день. Там случайно не высылается этот сигнал textChanged ещё и при форматировани текста? Если решиать в лоб, то можно просто отключать сигнал/слотовое соединение внутри слота и …

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