How to return focus to the window? - c++

After close MessageBox the focus self does not return to the window. I tried so:
QMessageBox msgBox;
msgBox.setText("Ok");
msgBox.exec();
this->setFocus();
How to return focus to the main window (this)?
//dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
void loadFile();
~Dialog();
private slots:
void on_buttonLoad2_clicked();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
//dialog.cpp
//
#include "dialog.h"
#include "ui_dialog.h"
#include <QDebug>
#include <QXmlStreamReader>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QEvent>
#include <QDomDocument>
#include <QDomElement>
#include <QFile>
#include <QMessageBox>
#include <QMediaPlayer>
#include <QListWidgetItem>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
this->setFocusPolicy(Qt::StrongFocus);
ui->setupUi(this);
}
void Dialog::loadFile()
{
QString urlForXML = "http://apifree.forvo.com/key//format/xml/action/word-pronunciations/word/";
urlForXML += ui->textHttp->toPlainText() + "/language/de";
QNetworkAccessManager m_NetworkMngr;
QNetworkReply *reply = m_NetworkMngr.get(QNetworkRequest(urlForXML));
QEventLoop loop;
connect(reply, SIGNAL(finished()),&loop, SLOT(quit()));
loop.exec();
QXmlStreamReader xmlReader;
xmlReader.addData(reply->readAll());
QString pathmp3Url;
while(!xmlReader.atEnd()) // пока не конец потока...
{
xmlReader.readNextStartElement(); // читаем следующий открывающий элемент (тег)
if (xmlReader.name() == "pathmp3") // если имя элемента "pathmp3"
{
pathmp3Url = xmlReader.readElementText();
break;
}
}
delete reply;
if(pathmp3Url.count())
{
QNetworkAccessManager m_NetworkMngr2;
QNetworkReply *reply2 = m_NetworkMngr2.get(QNetworkRequest(pathmp3Url));
QEventLoop loop2;
connect(reply2, SIGNAL(finished()), &loop2, SLOT(quit()));
loop2.exec();
QString qstring_mp3file = "/users/derkode/documents/forvoclient-mp3/" + ui->textHttp->toPlainText() + ".mp3";
QFile mp3_file(qstring_mp3file);
mp3_file.open(QIODevice::WriteOnly);
mp3_file.write(reply2->readAll());
QMediaPlayer *player = new QMediaPlayer;
player->setMedia(QUrl::fromLocalFile(qstring_mp3file));
player->setVolume(50);
player->play();
mp3_file.close();
delete reply2;
}
else
{
QMessageBox *msgBox = new QMessageBox(this);
msgBox->setText("Ok");
msgBox->exec();
this->setFocus();
}
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_buttonLoad2_clicked()
{
loadFile();
}

this->parent()->setFocus(); after msgBox->exec() (near end of your code)

Related

Redirecting std::cout from DLL in a separate thread to QTextEdit

The goal is to display all the application output shown in QtCreator to a QTextEdit as a debug console window so with the same application only those who have password are allowed to see the console window while normal users cannot. There is an exe with several dlls. All std::cout from DLLs and qDebug are needed to be shown in the debug console window.
To achieve this, I have followed
http://www.qtforum.org/article/39768/redirecting-std-cout-std-cerf-qdebug-to-qtextedit.html
The code works great for single thread but is hanged when a thread is started to call functions in DLL. I would like to know how to fix the problem.
code
In mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QObject>
#include <QThread>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_qd = new Q_DebugStream(std::cout,ui->textEdit); //Redirect Console output to QTextEdit
m_qd->Q_DebugStream::registerQDebugMessageHandler(); //Redirect qDebug() output to QTextEdit
connect(ui->pushButtonSingleThreadTest, SIGNAL(clicked()),this,SLOT(SingleThreadTest()));
connect(ui->pushButtonMultiThreadTest, SIGNAL(clicked()),this,SLOT(MultiThreadTest()));
}
void MainWindow::SingleThreadTest()
{
run();
}
void MainWindow::MultiThreadTest()
{
QThread *workerThread= new QThread;
ThreadWorker *worker = new ThreadWorker();
worker->moveToThread(workerThread);
connect(workerThread, SIGNAL(started()), worker, SLOT(doWork()));
connect(worker, SIGNAL(finished()), workerThread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
workerThread->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
In mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "q_debugstream.h"
#include "../ToyProj1/Header.h"
namespace Ui {
class MainWindow;
}
class ThreadWorker : public QObject
{
Q_OBJECT
public:
ThreadWorker()
{
}
private:
signals:
void finished();
public slots:
void doWork()
{
run();
emit finished();
}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void SingleThreadTest();
void MultiThreadTest();
private:
Ui::MainWindow *ui;
Q_DebugStream* m_qd;
};
#endif // MAINWINDOW_H
in q_debugstream.h
#ifndef Q_DEBUGSTREAM_H
#define Q_DEBUGSTREAM_H
#include <iostream>
#include <streambuf>
#include <string>
#include "QTextEdit.h"
class Q_DebugStream : public std::basic_streambuf<char>
{
public:
Q_DebugStream(std::ostream &stream, QTextEdit* text_edit) : m_stream(stream)
{
log_window = text_edit;
m_old_buf = stream.rdbuf();
stream.rdbuf(this);
}
~Q_DebugStream()
{
m_stream.rdbuf(m_old_buf);
}
static void registerQDebugMessageHandler(){
qInstallMessageHandler(myQDebugMessageHandler);
}
private:
static void myQDebugMessageHandler(QtMsgType, const QMessageLogContext &, const QString &msg)
{
std::cout << msg.toStdString().c_str();
}
protected:
//This is called when a std::endl has been inserted into the stream
virtual int_type overflow(int_type v)
{
if (v == '\n')
{
log_window->append("");
}
return v;
}
virtual std::streamsize xsputn(const char *p, std::streamsize n)
{
QString str(p);
if(str.contains("\n")){
QStringList strSplitted = str.split("\n");
log_window->moveCursor (QTextCursor::End);
log_window->insertPlainText (strSplitted.at(0)); //Index 0 is still on the same old line
for(int i = 1; i < strSplitted.size(); i++){
log_window->append(strSplitted.at(i));
}
}else{
log_window->moveCursor (QTextCursor::End);
log_window->insertPlainText (str);
}
return n;
}
private:
std::ostream &m_stream;
std::streambuf *m_old_buf;
QTextEdit* log_window;
};
#endif // Q_DEBUGSTREAM_H
In DLL,
int run()
{
std::cout << "Hello World" << std::endl;
return 0;
}
The code sample is uploaded to github for reference. Build ToyProj1 and ToyProj1GUI when repeat the problem.
https://github.com/kuwt/ToyProject.git
With the help comments in question, this solution works well with signal and slot mechanism. std::cout and qDebug are redirected to QTextEdit.
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
// Setup QMessageCatch
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
qInstallMessageHandler(MainWindow::QMessageOutput);
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QTextEdit>
#include "q_debugstream.h"
namespace Ui {
class MainWindow;
}
class ThreadWorker : public QObject
{
Q_OBJECT
public:
ThreadWorker()
{
}
private:
signals:
void finished();
public slots:
void doWork()
{
std::cout<< "Hello World2" <<std::endl;
qDebug() << "Hello World2q" ;
emit finished();
}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
// QMessage
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
static void QMessageOutput(QtMsgType , const QMessageLogContext &, const QString &msg);
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
public slots:
void SingleThreadTest();
void MultiThreadTest();
private:
Ui::MainWindow *ui;
// MessageHandler for display and ThreadLogStream for redirecting cout
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
MessageHandler *msgHandler = Q_NULLPTR;
ThreadLogStream* m_qd;
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QObject>
#include <QThread>
// Catch QMessage, redirect to cout
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
void MainWindow::QMessageOutput(QtMsgType , const QMessageLogContext &, const QString &msg)
{
std::cout<<msg.toStdString().c_str()<<std::endl;
}
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Set up ThreadLogStream, which redirect cout to signal sendLogString
// Set up MessageHandler, wgucg catch message from sendLogString and Display
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
m_qd = new ThreadLogStream(std::cout); //Redirect Console output to QTextEdit
this->msgHandler = new MessageHandler(this->ui->textEdit, this);
connect(m_qd, &ThreadLogStream::sendLogString, msgHandler, &MessageHandler::catchMessage);
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
connect(ui->pushButtonSingleThreadTest, SIGNAL(clicked()),this,SLOT(SingleThreadTest()));
connect(ui->pushButtonMultiThreadTest, SIGNAL(clicked()),this,SLOT(MultiThreadTest()));
}
void MainWindow::SingleThreadTest()
{
std::cout<< "Hello World1" <<std::endl;
qDebug() << "Hello World1q" ;
}
void MainWindow::MultiThreadTest()
{
QThread *workerThread= new QThread;
ThreadWorker *worker = new ThreadWorker();
worker->moveToThread(workerThread);
connect(workerThread, SIGNAL(started()), worker, SLOT(doWork()));
connect(worker, SIGNAL(finished()), workerThread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
workerThread->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
q_debugstream.h
#ifndef ThreadLogStream_H
#define ThreadLogStream_H
#include <iostream>
#include <streambuf>
#include <string>
#include <QScrollBar>
#include "QTextEdit"
#include "QDateTime"
// MessageHandler
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
class MessageHandler : public QObject
{
Q_OBJECT
public :
MessageHandler(QTextEdit *textEdit, QObject * parent = Q_NULLPTR) : QObject(parent), m_textEdit(textEdit){}
public slots:
void catchMessage(QString msg)
{
this->m_textEdit->append(msg);
}
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
private:
QTextEdit * m_textEdit;
};
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
class ThreadLogStream : public QObject, public std::basic_streambuf<char>
{
Q_OBJECT
public:
ThreadLogStream(std::ostream &stream, QObject * parent = Q_NULLPTR) :QObject(parent), m_stream(stream)
{
m_old_buf = stream.rdbuf();
stream.rdbuf(this);
}
~ThreadLogStream()
{
// output anything that is left
if (!m_string.empty())
{
emit sendLogString(QString::fromStdString(m_string));
}
m_stream.rdbuf(m_old_buf);
}
protected:
virtual int_type overflow(int_type v)
{
if (v == '\n')
{
emit sendLogString(QString::fromStdString(m_string));
m_string.erase(m_string.begin(), m_string.end());
}
else
m_string += v;
return v;
}
virtual std::streamsize xsputn(const char *p, std::streamsize n)
{
m_string.append(p, p + n);
long pos = 0;
while (pos != static_cast<long>(std::string::npos))
{
pos = static_cast<long>(m_string.find('\n'));
if (pos != static_cast<long>(std::string::npos))
{
std::string tmp(m_string.begin(), m_string.begin() + pos);
emit sendLogString(QString::fromStdString(tmp));
m_string.erase(m_string.begin(), m_string.begin() + pos + 1);
}
}
return n;
}
private:
std::ostream &m_stream;
std::streambuf *m_old_buf;
std::string m_string;
signals:
void sendLogString(const QString& str);
};
#endif // ThreadLogStream_H
for long transactions, you can add:
QCoreApplication::processEvents();
in the catchMessage(QString(msg) method of the class MessageHandler in q_debugstream.h, after the append() call.
This updates textEdit 'as soon as possible'.

Qt LCD display not working

I am trying to make the output of an http get connection stream to an lcd screen (a future http stock ticker), once connected. My code errors with “C:\Qt5\Tools\QtCreator\bin\httpGET\mainwindow.cpp:16: error: no matching function for call to ‘QLCDNumber::display() ui->lcdNumber->display()” I am unsure how to update display() properly
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
nam = new QNetworkAccessManager();
ui->lcdNumber->display(10);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::connect()
{
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
//ui->lcdNumber->display(10);
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(on_pushButton_clicked()));
}
void MainWindow::requestPage(){
QUrl url("http://www.google.com");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void MainWindow::finishedSlot(QNetworkReply* reply){
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (reply->error() == QNetworkReply::NoError)
{
QImageReader imageReader(reply);
QImage pic = imageReader.read();
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
}
else
{
}
}
void MainWindow::on_pushButton_clicked()
{
connect();
requestPage();
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QObject>
#include <QNetworkAccessManager>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
public slots:
void connect();
void requestPage();
void finishedSlot(QNetworkReply* reply);
void on_pushButton_clicked();
private slots:
private:
QNetworkAccessManager* nam;
};
#endif // MAINWINDOW_H
//main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow mConnect;
mConnect.show();
return a.exec();
}
moving display() fixed the lcd output issue.
if (reply->error() == QNetworkReply::NoError)
{
QImageReader imageReader(reply);
QImage pic = imageReader.read();
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
ui->lcdNumber->display(string);
}

Qt unable to access object data from my function

My code compiles error free but the output to a little lcd panel I have should read 22. It reads the number 44 which is the initial value set in the constuctor. It is failing to update to a new value.
It appears MainWindow::finishedSlot(QNetworkReply* reply) is not being accessed and ui->lcdNumber->display(22) does not update the object as expected.
I can confirm that the connection does establish, I have wireshark running and I can see the software try and reach google, but nothing about that LCD I can get working because I cannot access the constructor object.
The purpose of the LCD is to reflect connection information, but right now I am just trying to reach the constructor.
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
#include <QLCDNumber>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
nam = new QNetworkAccessManager();
ui->lcdNumber->display(44);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::connect()
{
qDebug() << "connect";
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(on_pushButton_clicked()));
}
void MainWindow::requestPage(){
QUrl url("http://www.google.com");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void MainWindow::finishedSlot(QNetworkReply* reply){
qDebug() << "finishedSlot";
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
ui->lcdNumber->display(22);
// if (reply->error() == QNetworkReply::NoError)
// {
// QImageReader imageReader(reply);
// QImage pic = imageReader.read();
// QByteArray bytes = reply->readAll(); // bytes
// QString string(bytes); // string
// ui->lcdNumber->display(22);
//qDebug()<<string;
// }
// else
// {
// }
}
void MainWindow::on_pushButton_clicked()
{
requestPage();
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QObject>
#include <QNetworkAccessManager>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
public slots:
void connect();
void requestPage();
void finishedSlot(QNetworkReply* reply);
void on_pushButton_clicked();
private slots:
private:
QNetworkAccessManager* nam;
};
#endif // MAINWINDOW_H
//main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow mConnect;
mConnect.show();
return a.exec();
}
Maybe it's me, but it seems that there's no connection between button clicked signal and on_pushButton_clicked slot.
Final working solution
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
#include <QLCDNumber>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
nam = new QNetworkAccessManager();
//connect2();
//on_pushButton_clicked();
QObject::connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(on_pushButton_clicked()));
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)));
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)));
ui->lcdNumber->display(66);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::connect2()
{
qDebug() << "connect";
//QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
//this, SLOT(finishedSlot(QNetworkReply*)));
//QObject::connect(nam, SIGNAL(clicked()), this, SLOT(finishedSlot(QNetworkReply* reply)));
//;
}
void MainWindow::requestPage(){
QUrl url("http://www.google.com");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void MainWindow::finishedSlot(QNetworkReply* reply){
qDebug() << "finishedSlot";
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
ui->lcdNumber->display(11);
qDebug()<<string;
// if (reply->error() == QNetworkReply::NoError)
// {
// QImageReader imageReader(reply);
// QImage pic = imageReader.read();
// QByteArray bytes = reply->readAll(); // bytes
// QString string(bytes); // string
// ui->lcdNumber->display(22);
//qDebug()<<string;
// }
// else
// {
// }
}
void MainWindow::on_pushButton_clicked()
{
requestPage();
//connect();
}

missing derived class with QObject

I am getting the error ~mainwindow.cpp:9: error: redefinition of 'MainWindow::MainWindow(QWidget*)' MainWindow::MainWindow(QWidget *parent) : and I am pretty sure it is complaining about the wrong derived class name. The base class is MainWindow but I do not see what the derived class would be.
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void coreEng::requestPage(){
QUrl url("http://www.nyctelecomm.com");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void coreEng::finishedSlot(QNetworkReply* reply){
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (reply->error() == QNetworkReply::NoError)
{
QImageReader imageReader(reply);
QImage pic = imageReader.read();
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
}
else
{
}
// delete reply();
}
void MainWindow::on_lcdNumber_overflow()
{
QByteArray replyData = netReply->readAll();
}
void MainWindow::on_pushButton_clicked()
{
QObject::on_pushButton_clicked(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QObject>
#include <QNetworkAccessManager>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0):
QMainWindow(parent)
{
nam = new QNetworkAccessManager();
}
~MainWindow();
private:
Ui::MainWindow *ui;
public slots:
//void connect();
void on_pushButton_clicked();
void requestPage();
void finishedSlot(QNetworkReply* reply);
private slots:
void on_lcdNumber_overflow();
private:
QNetworkAccessManager* nam;
};
#endif // MAINWINDOW_H
//main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow mConnect;
mConnect.on_pushButton_clicked();
mConnect.requestPage();
MainWindow w;
w.show();
return a.exec();
}
You have defined MainWindow::MainWindow two times. First in header file and second in source file. That is said in error message.
explicit MainWindow(QWidget *parent = 0):
QMainWindow(parent)
{
nam = new QNetworkAccessManager();
}
//
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}

How can i download file from the internet in Qt?

I don't know what the problem is...The compiler (Qt) runs program without errors, but the file is not downloaded...
Can you tell me please tell what is wrong?
I made by example "download", which is located in the qt folder. The only difference is that they have is a console, and I have windows application.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtNetwork>
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
class DownloadManager: public QObject
{
Q_OBJECT
QNetworkAccessManager manager;
QList<QNetworkReply *> currentDownloads;
public:
DownloadManager();
void doDownload(const QUrl &url);
QString saveFileName(const QUrl &url);
bool saveToDisk(const QString &filename, QIODevice *data);
public slots:
void execute();
void downloadFinished(QNetworkReply *reply);
};
#endif // MAINWINDOW_H
main.cpp
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QtNetwork>
#include <QNetworkAccessManager>
#include <QStringList>
#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QList>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QStringList>
#include <QTimer>
#include <QUrl>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
#if defined(Q_WS_S60)
w.showMaximized();
#else
w.show();
#endif
return a.exec();
}
DownloadManager::DownloadManager()
{
connect(&manager, SIGNAL(finished(QNetworkReply*)),
SLOT(downloadFinished(QNetworkReply*)));
}
void DownloadManager::doDownload(const QUrl &url)
{
QNetworkRequest request(url);
QNetworkReply *reply = manager.get(request);
currentDownloads.append(reply);
}
QString DownloadManager::saveFileName(const QUrl &url)
{
QString path = url.path();
QString basename = QFileInfo(path).fileName();
if (basename.isEmpty())
basename = "download";
if (QFile::exists(basename)) {
// already exists, don't overwrite
int i = 0;
basename += '.';
while (QFile::exists(basename + QString::number(i)))
++i;
basename += QString::number(i);
}
return basename;
}
bool DownloadManager::saveToDisk(const QString &filename, QIODevice *data)
{
QFile file(filename);
if (!file.open(QIODevice::WriteOnly)) {
fprintf(stderr, "Could not open %s for writing: %s\n",
qPrintable(filename),
qPrintable(file.errorString()));
return false;
}
file.write(data->readAll());
file.close();
return true;
}
void DownloadManager::execute()
{
QStringList args = QCoreApplication::instance()->arguments();
args[0]="http://www.google.ru/images/srpr/logo3w.png";
QString arg=args[0];
QUrl url = QUrl::fromEncoded(arg.toLocal8Bit());
doDownload(url);
}
void DownloadManager::downloadFinished(QNetworkReply *reply)
{
QUrl url = reply->url();
if (reply->error()) {
fprintf(stderr, "Download of %s failed: %s\n",
url.toEncoded().constData(),
qPrintable(reply->errorString()));
} else {
QString filename = saveFileName(url);
if (saveToDisk(filename, reply))
printf("Download of %s succeded (saved to %s)\n",
url.toEncoded().constData(), qPrintable(filename));
}
currentDownloads.removeAll(reply);
reply->deleteLater();
if (currentDownloads.isEmpty())
// all downloads finished
QCoreApplication::instance()->quit();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
DownloadManager manager;
manager.execute();
QTimer::singleShot(0, &manager, SLOT(execute()));
}
The problem is at that point of your code:
void MainWindow::on_pushButton_clicked()
{
DownloadManager manager;
manager.execute();
}
QNetworkAccessManager is asynchronous, so it needs an event loop to do any downloading. But when the function on_pushButton_clicked() returns and gives the control back to the event loop, the QNetworkAccessManager is already destroyed, and didn't have the time to do anything.
When you add a QMessageBox in DownloadManager::execute, you are in fact running another event loop withing the slot on_pushButton_clicked(), and it gives the opportunity to the QNetworkAccessManager to do its work.
The correct solution would be to allocate DownloadManager dynamically, and eventually to make it destroy itself when it has finished all downloads.
void MainWindow::on_pushButton_clicked()
{
DownloadManager *manager = new DownloadManager(this);
manager->execute();
}
void DownloadManager::downloadFinished(QNetworkReply *reply)
{
...
if (currentDownloads.isEmpty())
this->deleteLater();
}