I am trying to connect to a FTP server but I got the following issue :
QObject::connect: No such slot Object::replyFinished
in ...\ here my program name ......
Where is my mistake? I suppose it is in the following code :
///////////////Connection.h file////////
class Connection : public QObject
{
public:
explicit Connection(QObject *parent=0);
Connection(QString uri, QString usernmae, QString password);
void FTP_Connection();
public slots:
void replyFinished(QNetworkReply *);
private:
QString URI;
QString USERNAME;
QString PASSWORD;
QNetworkAccessManager *manager;
};
///////////////Connection.cpp file////////
Connection::Connection(QString uri, QString usernmae, QString password)
{
this->URI=uri;
this->USERNAME=usernmae;
this->PASSWORD=password;
}
void Connection::FTP_Connection()
{
QUrl url(this->URI);
url.setUserName(this->USERNAME);
url.setPassword(this->PASSWORD);
url.setPort(21);
QNetworkRequest request(url);
manager=new QNetworkAccessManager(this);
connect(manager,
SIGNAL(finished(QNetworkReply*)),
this,
SLOT(replyFinished(QNetworkReply *)));
manager->get(request);
}
///////////////main.cpp file////////
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Connection *con=new Connection("ftp://192.168.3.62//",
"win7",
"053253");
con->FTP_Connection();
return a.exec();
}
Related
First things first, I'm a newbie in QT so don't blame me. I know that many similar questions have been in the forum, but I couldn't solve my problem.
Problem description. I want to have a GUI application that receives and parses data and update some qt widget. Formerly I did them all in the Mainwindow thread, but since it hangs, I tried to make it multi-threaded. But it still hangs when I try to update GUI data as fast as 10 ms.
Now, this is what I have tried.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
class Parser : public QThread , public QRunnable
{
Q_OBJECT
public:
explicit Parser(QThread *parent = nullptr);
~Parser();
signals:
void data1Available(unsigned char*);
void data2Available(unsigned char*);
void finished();
// QRunnable interface
public:
void run();
public slots:
void parse();
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect( &SerialPort, SIGNAL(readyRead()), this, SLOT(ReadData()) );
QThread* thread = new QThread;
thread->setObjectName("Parser Thread");
qInfo()<<"Parser Thread";
Parser* parser= new Parser();
parser->moveToThread(thread);
QObject::connect(thread,&QThread::started,parser,&Parser::run);
QObject::connect(parser,&Parser::finished,parser,&Parser::deleteLater);
QObject::connect(parser,&Parser::finished,thread,&QThread::quit);
QObject::connect(thread,&QThread::finished,thread,&QThread::deleteLater);
QObject::connect(parser,SIGNAL(data1Available(unsigned char *)),this,SLOT(on_data1Available(unsigned char *)));
QObject::connect(parser,SIGNAL(data2Available(unsigned char *)),this,SLOT(on_data2Available(unsigned char *)));
thread->start();
}
void MainWindow::ReadData()
{
QByteArray Data = SerialPort.readAll();
for (unsigned char i=0;i<Data.length();i++)
circBuff.append(Data[i]);
}
void MainWindow::on_data1Available(unsigned char* tempData)
{
ui->label1->setNum(tempData[5]);
}
void MainWindow::on_data2Available(unsigned char* tempData)
{
ui->label2->setNum(tempData[7]);
}
void Parser::run()
{
qInfo()<<this<<Q_FUNC_INFO<<QThread::currentThread();
QScopedPointer<QEventLoop> loop (new QEventLoop);
QScopedPointer<QTimer> timer (new QTimer);
timer->setInterval(5);
connect(timer.data(),&QTimer::timeout,this,&Parser::parse);
connect(this,&Parser::finished,loop.data(),&QEventLoop::quit);
timer->start();
loop->exec();
qInfo()<<this<<"Finished... "<<QThread::currentThread();
}
void Parser::parse()
{
unsigned char tempData[16];
while (1)
{
while (circBuff.size()>=16)
{
if ( )
{
if ()
emit data1Available(tempData);
else
emit data2Available(tempData);
}
}
}
emit finished();
}
I'm trying to create a simple login app, which will authenticate via Google Firebase. So far, I have the authentication code working fine.
Header file:
#ifndef AUTHHANDLER_H
#define AUTHHANDLER_H
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QJsonDocument>
class AuthHandler : public QObject
{
Q_OBJECT
public:
explicit AuthHandler(QObject *parent = nullptr);
~AuthHandler();
void setAPIKey(const QString & apiKey);
void signUserUp(const QString & emailAddress, const QString & password);
void signUserIn(const QString & emailAddress, const QString & password);
public slots:
void networkReplyReadyRead();
void performAuthenticatedDatabaseCall();
signals:
void userSignedIn();
private:
void performPOST( const QString & url, const QJsonDocument & payload);
void parseResponse( const QByteArray & response);
QString m_apiKey;
QNetworkAccessManager * m_networkAccessManager;
QNetworkReply * m_networkReply;
QString m_idToken;
};
#endif // AUTHHANDLER_H
Authentication .cpp file
#include "authhandler.h"
#include <QDebug>
#include <QVariantMap>
#include <QNetworkRequest>
#include <QJsonObject>
AuthHandler::AuthHandler(QObject *parent)
: QObject{parent}
, m_apiKey( QString() )
{
m_networkAccessManager = new QNetworkAccessManager( this );
connect( this, &AuthHandler::userSignedIn, this, &AuthHandler::performAuthenticatedDatabaseCall );
}
AuthHandler::~AuthHandler()
{
m_networkAccessManager->deleteLater();
}
void AuthHandler::setAPIKey(const QString &apiKey)
{
m_apiKey = apiKey;
}
void AuthHandler::signUserUp(const QString &emailAddress, const QString &password)
{
QString signUpEndpoint = "https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=" + m_apiKey;
QVariantMap variantPayload;
variantPayload["email"] = emailAddress;
variantPayload["password"] = password;
variantPayload["returnSecureToken"] = true;
QJsonDocument jsonPayload = QJsonDocument::fromVariant( variantPayload );
performPOST( signUpEndpoint, jsonPayload);
}
void AuthHandler::signUserIn(const QString &emailAddress, const QString &password)
{
QString signInEndpoint = "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=" + m_apiKey;
QVariantMap variantPayload;
variantPayload["email"] = emailAddress;
variantPayload["password"] = password;
variantPayload["returnSecureToken"] = true;
QJsonDocument jsonPayload = QJsonDocument::fromVariant( variantPayload );
performPOST( signInEndpoint, jsonPayload);
}
main.cpp file
#include <QCoreApplication>
#include "authhandler.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
//QCoreApplication a(argc, argv);
// AuthHandler authHandler;
//authHandler.setAPIKey("AIzaSyB-nAN8OlgxHzXC5gpISkodjEZJ7IdSpgI");
// authHandler.signUserIn("user2#user.com", "password123!");
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
AuthHandler authHandler;
authHandler.setAPIKey("AIzaSyB-nAN8OlgxHzXC5gpISkodjEZJ7IdSpgI");
authHandler.signUserIn("user3#user.com", "password123!");
return app.exec();
}
As you can see, I'm currently hardcoding the values used in the SignUserIn function. These values are then updated in Firebase, and this is working. My question is, how do I make it so that the hard-coded values are input by an user in a qml file? I created a qml file with the required layout, but I'm having trouble setting it up so that the .cpp file function executes when a button is clicked in qml.
Make the method signUserIn a slot in the AuthHandler class
public slots:
void signUserIn(const QString & emailAddress, const QString & password);
Register your AuthHandler to the QML engine in main.cpp
qmlRegisterSingletonInstance("AuthHandler", 1, 0, "AuthHandler", &authHandler);
Import the AuthHandler in QML
import AuthHandler
Send the user credentials from QML to your handler
TextEdit {
id: user
text: "user"
}
TextEdit {
id: password
text: "password"
}
Button {
text: qsTr("Login");
onClicked: {
console.log("login: " + user.text + " password: " + password.text);
AuthHandler.signUserIn(user.text, password.text);
}
}
Qcompleter which is associated with a lineEdit doesn't work in the slot of a QNetworkRequest finished.The Qcompleter disappeared quite quickly.Each time the text in lineEdit changed a request was send.I tried a demo without other code,it also occured.
Every time the text in lineEdit was edit,a request contains the text will be send to my server.And then I want to show the content in reply in a Qcompleter.But the prompt disappears in a instant.
void MainWindow::onRequestFinished(QNetworkReply* reply){
QStringList stringList;
stringList << "test1" <<"test2"<<"test3";
QCompleter* completer = new QCompleter(stringList,this);
completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
ui->lineEdit->setCompleter(completer);
reply->deleteLater();
}
void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
QUrl url("http://www.google.com");
QNetworkRequest request;
request.setUrl(url);
manager->get(request);
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow){
...
this->manager = new QNetworkAccessManager(this);
connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(onRequestFinished(QNetworkReply*)));
...
}
The logic is similar to an old answer of mine, in it a model is created that will store the information this prevents you from creating a QCompleter at every moment avoiding the problem the disappearance of the popup.
#include <QtWidgets>
#include <QtNetwork>
class SuggestModel: public QStandardItemModel
{
Q_OBJECT
public:
using QStandardItemModel::QStandardItemModel;
void search(const QString & text)
{
QNetworkRequest request = create_request(text);
if(m_reply)
m_reply->abort();
m_reply = manager.get(request);
connect(m_reply, &QNetworkReply::finished, this, &SuggestModel::onFinished);
QEventLoop loop;
connect(this, &SuggestModel::finished, &loop, &QEventLoop::quit);
loop.exec();
}
private Q_SLOTS:
void onFinished(){
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
QUrl url = reply->url();
if (reply->error() == QNetworkReply::NoError) {
QVector<QString> choices;
QByteArray response(reply->readAll());
QXmlStreamReader xml(response);
while (!xml.atEnd()) {
xml.readNext();
if (xml.tokenType() == QXmlStreamReader::StartElement)
if (xml.name() == "suggestion") {
QStringRef str = xml.attributes().value("data");
choices << str.toString();
}
}
clear();
for(const QString & choice: choices)
appendRow(new QStandardItem(choice));
}
reply->deleteLater();
Q_EMIT finished();
m_reply = nullptr;
}
Q_SIGNALS:
void finished();
private:
QNetworkRequest create_request(const QString & text){
const QString suggestUrl(QStringLiteral("http://google.com/complete/search?output=toolbar&q=%1"));
QString url = suggestUrl.arg(text);
return QNetworkRequest(url);
}
QNetworkAccessManager manager;
QNetworkReply *m_reply = nullptr;
};
class SuggestCompleter: public QCompleter{
public:
SuggestCompleter(QObject *parent=nullptr):
QCompleter(parent)
{
SuggestModel *m_model = new SuggestModel(this);
setModel(m_model);
setCompletionMode(QCompleter::UnfilteredPopupCompletion);
}
QStringList splitPath(const QString &path) const override{
if(SuggestModel * m = qobject_cast<SuggestModel *>(model()))
m->search(path);
return QCompleter::splitPath(path);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLineEdit le;
le.setCompleter(new SuggestCompleter(&le));
le.show();
return a.exec();
}
#include "main.moc"
I wrote a piece of code that sends me, via a post request, a json to my API Rest; and works!
main.cpp
void replyFinished(QNetworkReply *reply)
{
reply->deleteLater();
qDebug() << "reply delete!";
qDebug() << "https post_request done!";
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QNetworkAccessManager *manager = new QNetworkAccessManager();
QUrl url("https://.../");
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QObject::connect(manager, &QNetworkAccessManager::finished, replyFinished);
quint8 speed = 0x12;
quint8 accelleration = 0x2b;
QString json = QString("{\"speed\":\"%1\",\"acceleration\":\"%2\"}").arg(speed).arg(accelleration);
manager->post(request, json.toUtf8());
return a.exec();
}
But when I want to integrate this piece of code in my program, it does not work. Briefly, my program gets through the SIGNAL and SLOT mechanism, a QByteArray, from which I take the data and I send them to my API Rest.
This is my Header.h
...
class Packet : public QObject
{
Q_OBJECT
public:
Packet();
public slots:
void receivePayload(QByteArray &bufferToJson);
void replyFinished(QNetworkReply *reply);
private:
QNetworkAccessManager *m_manager;
quint8 m_speed;
quint8 m_accelleration;
public:
QString json;
};
...
This is my class.cpp
Packet::Packet()
: m_manager { new QNetworkAccessManager }
{
QObject::connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
}
void Packet::replyFinished(QNetworkReply *reply)
{
reply->deleteLater();
qDebug() << "reply delete!";
qDebug() << "https post_request done!";
}
void Packet::receivePayload(QByteArray &bufferToJson){
m_speed = bufferToJson.at(0);
m_accelleration = bufferToJson.at(1);
QUrl url("https://.../");
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QString json = QString("{\"speed\":\"%1\",\"acceleration\":\"%2\"}").arg(m_speed).arg(m_accelleration);
m_manager->post(request, json.toUtf8());
}
What's the problem of my change?
i am a beginner in c++ and i am trying to retrieve data from a website using http request and to download the data in a file .
I am using the classes :
QMainWindow
QtNetwork/QNetworkAccessManager
QtNetwork/QNetworkRequest
QtNetwork/QNetworkReply
QUrl
The thing is that the file is created but there is no data in the file and i am getting an error that i don't understand . I searched through the forum found some similar kind of problems but did not understand as i am a beginner . Please help me its a school project and i am really stuck here.
Here is the httpWindow.h code
#ifndef HTTPWINDOW_H
#define HTTPWINDOW_H
#include <QMainWindow>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QUrl>
#include <QString>
class QFile;
namespace Ui {
class httpWindow;
}
class httpWindow : public QMainWindow
{
Q_OBJECT
public:
explicit httpWindow(QWidget *parent = 0);
~httpWindow();
void request(QUrl url);
private slots:
void downloadFile();
void httpFinished();
void httpReadyRead();
private:
Ui::httpWindow *ui;
QUrl url;
QNetworkAccessManager *manager;
QNetworkRequest requete;
QNetworkReply *reply;
QFile *file;
int httpGetId;
bool httpRequestAborted;
};
#endif // HTTPWINDOW_H
Here is the httpwindow.cpp
#include <QtWidgets>
#include <qnetwork.h>
#include <QString>
#include "httpwindow.h"
#include "ui_httpwindow.h"
httpWindow::httpWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::httpWindow)
{
ui->setupUi(this);
downloadFile();
}
httpWindow::~httpWindow()
{
delete ui;
}
void httpWindow::request(QUrl url)
{
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished()),
this, SLOT(httpFinished()));
//requete.setUrl(QUrl("http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide"));
requete.setUrl(url);
reply = manager->get(requete);
connect(reply, SIGNAL(&reply::readyRead()), this, SLOT(httpReadyRead()));
}
void httpWindow::downloadFile()
{
QMessageBox msg ;
QUrl url("http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide") ;
qDebug() << url.toString();
QFileInfo fileInfo(url.path());
//msg.setText("fileInfo = " + fileInfo);
QString fileName = "C:\\testQt\\" + fileInfo.fileName();
msg.setText("fileName = " + fileName);
if (fileName.isEmpty()){
fileName = "C:\testQt\fichier.html";
msg.setText(" création d'un nouveau fichier fichier.html ");
}
if (QFile::exists(fileName)) {
QFile::remove(fileName);
return;
}
file = new QFile(fileName);
msg.setText(" QFile::exists(fileName) == true , file : ");
if (!file->open(QIODevice::WriteOnly)) {
delete file;
file = 0;
return;
}
// schedule the request
httpRequestAborted = false;
request(url);
}
void httpWindow::httpFinished()
{
if (httpRequestAborted) {
if (file) {
file->close();
file->remove();
delete file;
file = 0;
}
reply->deleteLater();
return;
}
file->flush();
file->close();
QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (reply->error()) {
file->remove();
// QMessageBox::information(this, tr("HTTP"),
// tr("Download failed: %1.")
// .arg(reply->errorString()));
// downloadButton->setEnabled(true);
} else if (!redirectionTarget.isNull()) {
QUrl newUrl = url.resolved(redirectionTarget.toUrl());
// if (QMessageBox::question(this, tr("HTTP"),
// tr("Redirect to %1 ?").arg(newUrl.toString()),
// QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
url = newUrl;
reply->deleteLater();
file->open(QIODevice::WriteOnly);
file->resize(0);
request(url);
return;
}
reply->deleteLater();
reply = 0;
delete file;
file = 0;
}
void httpWindow::httpReadyRead()
{
// this slot gets called every time the QNetworkReply has new data.
// We read all of its new data and write it into the file.
// That way we use less RAM than when reading it at the finished()
// signal of the QNetworkReply
if (file)
file->write(reply->readAll());
}
Here is the main.cpp code
#include "httpwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
httpWindow w;
w.show();
return a.exec();
}
The errors :
can't find linker symbol for virtual table for `QMessageBox' value
found `RGB_MASK' instead
can't find linker symbol for virtual table for `QMessageBox' value
found `RGB_MASK' instead
"http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide"
QObject::connect: No such signal QNetworkAccessManager::finished() in ..\ppe3_trading_test\httpwindow.cpp:24
QObject::connect: (receiver name: 'httpWindow')
QObject::connect: No such signal QNetworkReplyHttpImpl::&reply::readyRead() in ..\ppe3_trading_test\httpwindow.cpp:31
QObject::connect: (receiver name: 'httpWindow')
Please do help me its really important for my schooling .
connect(reply, SIGNAL(&reply::readyRead()), this, SLOT(httpReadyRead()));
You're mixing up old syntax and new syntax, it should be
connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
or better yet using new syntax(Qt5 only):
connect(reply, &QNetworkReply::readyRead, this, &httpWindow::httpReadyRead);
QNetworkAccessManager doesn't have a finished() signal it has a finished(QNetworkReply*) signal, read the docs.