QT信号&插槽,插槽未在信号发射时调用
我一直在遇到这个问题已有几周了,但在任何地方都没有找到解决方案。我竭尽所能找到问题,一切看起来都不错,但由于某种原因,它不起作用。 我测试了loginfailed()信号和handleloginfailed()插槽之间的连接,它返回了,打印了对象信息,它显示了连接。尝试了不同的QT ::连接类型,没有任何可用。
这两个对象被定义为波纹管。
loginService.h
#ifndef LOGINSERVICE_H
#define LOGINSERVICE_H
#include <QObject>
#include <QVariant>
#include "libs/qubeapi/QubeAPI.h"
#include "libs/qubeapi/LoginCommand.h"
#include "libs/qubeapi/APIBridge.h"
#include "libs/mge-users/User.h"
#include "libs/mge-users/permissionfactory.h"
#include "Utils/serverstate.h"
#include "Utils/singleton.h"
#include "Utils/baseservice.h"
class LoginService : public QObject
{
Q_OBJECT
QubeAPI* api;
APIBridge* bridge;
LoginCommand* loginCmd;
QString m_userType;
QString m_firstName;
QString m_lastName;
User *m_user;
public:
explicit LoginService(QObject *parent = nullptr);
Q_PROPERTY(QString userType READ userType WRITE setUserType NOTIFY userTypeChanged)
Q_PROPERTY(QString firstName READ firstName WRITE setFirstName NOTIFY firstNameChanged)
Q_PROPERTY(QString lastName READ lastName WRITE setLastName NOTIFY lastNameChanged)
Q_PROPERTY(User* user READ user WRITE setUser NOTIFY userChanged)
const QString &userType() const;
void setUserType(const QString &newUserType);
const QString &firstName() const;
void setFirstName(const QString &newFirstName);
const QString &lastName() const;
void setLastName(const QString &newLastName);
User *user() const;
void setUser(User *newUser);
signals:
void success(QString token);
void loginFailed();
void userTypeChanged();
void firstNameChanged();
void lastNameChanged();
void staffLogout();
void userTypeRecived();
void userChanged();
public slots:
void requestLogin(QString userName, QString password);
void loginResponse(QString jsonData);
void doClose();
void prepareGetUserType();
void loadUserType(QString jsonData);
};
#endif // LOGINCONTROLLER_H
发出信号的函数:
void LoginService::loginResponse(QString jsonData)
{
QSignalSpy spy(this,SIGNAL(loginFailed()));
if(jsonData == "") {
emit Singleton<ServerState>::GetInstance().offlineServer();
return;
}
QJsonDocument doc = QJsonDocument::fromJson(jsonData.toUtf8());
QString token = doc["data"]["tokenAuth"]["token"].toString();
if(!token.isEmpty()) {
UserSession::getInstance()->setAuthToken(token);
emit success(token);
prepareGetUserType();
} else {
qDebug() << "Urmeaza eroare";
QString errorMsg = doc["errors"][0]["message"].toString();
emit loginFailed();
qDebug() << spy.count();
}
}
具有插槽的控制器类:
#ifndef LOGINCONTROLLER_H
#define LOGINCONTROLLER_H
#include <Utils/basecontroller.h>
#include <Utils/enginefactory.h>
#include <Utils/singleton.h>
#include <QQuickWindow>
#include <QQuickItem>
#include <QThread>
#include <QProperty>
#include <QQmlProperty>
#include "loginservice.h"
#include "draggableviewhelper.h"
#include <QMouseEvent>
class LoginController : public BaseController
{
Q_OBJECT
private:
QQuickWindow* window;
QQuickItem* login;
QQuickItem* userTextField;
QQuickItem* passwordTextField;
DraggableViewHelper* draggableViewHelper;
QQuickItem* mouseArea;
LoginService* service;
QPointF lastMousePosition;
public:
explicit LoginController(QObject *parent = nullptr);
// BaseController interface
void initialize();
// void setService(BaseService* s);
void setService(LoginService* s);
void setLastMousePosition(QPointF lastMousePosition);
public slots:
void handleLoginResponseSuccess(QString loginResponse);
void handleLoginResponseFailed();
void handlePositionChanged();
void handleLogout();
};
#endif // LOGINCONTROLLER_H
初始化器方法
void LoginController::initialize()
{
this->engine = Singleton<EngineFactory*>::GetInstance()->createEngine("qrc:/qml/LoginWindow.qml");
this->window = qobject_cast<QQuickWindow*>(this->engine->rootObjects().first());
// Create a draggable view helper, use window as input
// Get the view from the engine
this->draggableViewHelper = new DraggableViewHelper(this->window);
this->window->setFlags(Qt::Window | Qt::FramelessWindowHint);
this->login = window->findChild<QQuickItem*>("login");
this->userTextField = QQmlProperty::read(this->login,"user").value<QQuickItem*>();
this->passwordTextField = QQmlProperty::read(this->login,"password").value<QQuickItem*>();
// Set the mouseArea with the mainMouseArea item of the window
this->mouseArea = window->findChild<QQuickItem*>("mainMouseArea");
// Connect onClicked from mouse area, to handleMove of this
QObject::connect(this->mouseArea,SIGNAL(positionMoved()),this,SLOT(handlePositionChanged()));
}
void LoginController::setService(LoginService *s)
{
this->service = s;//new LoginService;
connect(this->service,SIGNAL(loginFailed()),this,SLOT(handleLoginResponseFailed()));
connect(this->service,SIGNAL(success(QString)),this,SLOT(handleLoginResponseSuccess(QString)));
connect(login,SIGNAL(doLogin(QString,QString)),this->service,SLOT(requestLogin(QString,QString)));
this->dumpObjectInfo();
this->service->dumpObjectInfo();
}
插槽
void LoginController::handleLoginResponseFailed()
{
qDebug() << "Failed";
QQmlProperty::write(this->userTextField,"state",QVariant::fromValue(QString{"default-error"}));
QQmlProperty::write(this->passwordTextField,"state",QVariant::fromValue(QString{"password-error"}));
}
这是main.cpp文件,其中创建对象是
QApplication app1(argc, argv);
LoginController* loginCtrl = new LoginController;
LoginService* loginService = new LoginService;
QObject::connect(loginService, &LoginService::userTypeRecived,[&](){
qDebug() << "Failed to login";
});
qDebug() << loginService;
loginCtrl->initialize();
loginCtrl->setService(loginService);
//This will trigger the signal
// loginService->loginResponse("{\"errors\":[{\"message\":\"Please enter valid credentials\",\"locations\":[{\"line\":1,\"column\":12}],\"path\":[\"tokenAuth\"]}],\"data\":{\"tokenAuth\":null}}");
return app1.exec();
I've been having this problem for few weeks, still didn't found a solution anywhere. I did everything I could to find the problem, everything looks good but for some reason it doesn't work.
I tested the connection, between the loginFailed() signal, and handleLoginFailed() slot, it returned True, printed the object info, it shows the connections. Tried different Qt::connectionTypes, nothing works.
The two objects are defined bellow.
LoginService.h
#ifndef LOGINSERVICE_H
#define LOGINSERVICE_H
#include <QObject>
#include <QVariant>
#include "libs/qubeapi/QubeAPI.h"
#include "libs/qubeapi/LoginCommand.h"
#include "libs/qubeapi/APIBridge.h"
#include "libs/mge-users/User.h"
#include "libs/mge-users/permissionfactory.h"
#include "Utils/serverstate.h"
#include "Utils/singleton.h"
#include "Utils/baseservice.h"
class LoginService : public QObject
{
Q_OBJECT
QubeAPI* api;
APIBridge* bridge;
LoginCommand* loginCmd;
QString m_userType;
QString m_firstName;
QString m_lastName;
User *m_user;
public:
explicit LoginService(QObject *parent = nullptr);
Q_PROPERTY(QString userType READ userType WRITE setUserType NOTIFY userTypeChanged)
Q_PROPERTY(QString firstName READ firstName WRITE setFirstName NOTIFY firstNameChanged)
Q_PROPERTY(QString lastName READ lastName WRITE setLastName NOTIFY lastNameChanged)
Q_PROPERTY(User* user READ user WRITE setUser NOTIFY userChanged)
const QString &userType() const;
void setUserType(const QString &newUserType);
const QString &firstName() const;
void setFirstName(const QString &newFirstName);
const QString &lastName() const;
void setLastName(const QString &newLastName);
User *user() const;
void setUser(User *newUser);
signals:
void success(QString token);
void loginFailed();
void userTypeChanged();
void firstNameChanged();
void lastNameChanged();
void staffLogout();
void userTypeRecived();
void userChanged();
public slots:
void requestLogin(QString userName, QString password);
void loginResponse(QString jsonData);
void doClose();
void prepareGetUserType();
void loadUserType(QString jsonData);
};
#endif // LOGINCONTROLLER_H
The function that emits the signal:
void LoginService::loginResponse(QString jsonData)
{
QSignalSpy spy(this,SIGNAL(loginFailed()));
if(jsonData == "") {
emit Singleton<ServerState>::GetInstance().offlineServer();
return;
}
QJsonDocument doc = QJsonDocument::fromJson(jsonData.toUtf8());
QString token = doc["data"]["tokenAuth"]["token"].toString();
if(!token.isEmpty()) {
UserSession::getInstance()->setAuthToken(token);
emit success(token);
prepareGetUserType();
} else {
qDebug() << "Urmeaza eroare";
QString errorMsg = doc["errors"][0]["message"].toString();
emit loginFailed();
qDebug() << spy.count();
}
}
The controller class that has the slot:
#ifndef LOGINCONTROLLER_H
#define LOGINCONTROLLER_H
#include <Utils/basecontroller.h>
#include <Utils/enginefactory.h>
#include <Utils/singleton.h>
#include <QQuickWindow>
#include <QQuickItem>
#include <QThread>
#include <QProperty>
#include <QQmlProperty>
#include "loginservice.h"
#include "draggableviewhelper.h"
#include <QMouseEvent>
class LoginController : public BaseController
{
Q_OBJECT
private:
QQuickWindow* window;
QQuickItem* login;
QQuickItem* userTextField;
QQuickItem* passwordTextField;
DraggableViewHelper* draggableViewHelper;
QQuickItem* mouseArea;
LoginService* service;
QPointF lastMousePosition;
public:
explicit LoginController(QObject *parent = nullptr);
// BaseController interface
void initialize();
// void setService(BaseService* s);
void setService(LoginService* s);
void setLastMousePosition(QPointF lastMousePosition);
public slots:
void handleLoginResponseSuccess(QString loginResponse);
void handleLoginResponseFailed();
void handlePositionChanged();
void handleLogout();
};
#endif // LOGINCONTROLLER_H
The initializer methods
void LoginController::initialize()
{
this->engine = Singleton<EngineFactory*>::GetInstance()->createEngine("qrc:/qml/LoginWindow.qml");
this->window = qobject_cast<QQuickWindow*>(this->engine->rootObjects().first());
// Create a draggable view helper, use window as input
// Get the view from the engine
this->draggableViewHelper = new DraggableViewHelper(this->window);
this->window->setFlags(Qt::Window | Qt::FramelessWindowHint);
this->login = window->findChild<QQuickItem*>("login");
this->userTextField = QQmlProperty::read(this->login,"user").value<QQuickItem*>();
this->passwordTextField = QQmlProperty::read(this->login,"password").value<QQuickItem*>();
// Set the mouseArea with the mainMouseArea item of the window
this->mouseArea = window->findChild<QQuickItem*>("mainMouseArea");
// Connect onClicked from mouse area, to handleMove of this
QObject::connect(this->mouseArea,SIGNAL(positionMoved()),this,SLOT(handlePositionChanged()));
}
void LoginController::setService(LoginService *s)
{
this->service = s;//new LoginService;
connect(this->service,SIGNAL(loginFailed()),this,SLOT(handleLoginResponseFailed()));
connect(this->service,SIGNAL(success(QString)),this,SLOT(handleLoginResponseSuccess(QString)));
connect(login,SIGNAL(doLogin(QString,QString)),this->service,SLOT(requestLogin(QString,QString)));
this->dumpObjectInfo();
this->service->dumpObjectInfo();
}
The slot
void LoginController::handleLoginResponseFailed()
{
qDebug() << "Failed";
QQmlProperty::write(this->userTextField,"state",QVariant::fromValue(QString{"default-error"}));
QQmlProperty::write(this->passwordTextField,"state",QVariant::fromValue(QString{"password-error"}));
}
This is the main.cpp file, where the objects are created
QApplication app1(argc, argv);
LoginController* loginCtrl = new LoginController;
LoginService* loginService = new LoginService;
QObject::connect(loginService, &LoginService::userTypeRecived,[&](){
qDebug() << "Failed to login";
});
qDebug() << loginService;
loginCtrl->initialize();
loginCtrl->setService(loginService);
//This will trigger the signal
// loginService->loginResponse("{\"errors\":[{\"message\":\"Please enter valid credentials\",\"locations\":[{\"line\":1,\"column\":12}],\"path\":[\"tokenAuth\"]}],\"data\":{\"tokenAuth\":null}}");
return app1.exec();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论