everyone. First I want to apologize for my bad English. Here is the code of one of my personal project and I need help. The current code at execution should download this video - http://media09.vbox7.com/s/21/21bbc2dca3r3634e3389.mp4, but does not work. The video is downloaded only when the following code be placed in
// main.cpp
int main (int argc, char * argv [])
{
QApplication a (argc, argv);
MainWindow w;
w.show ();
QtDownload dl;
dl.setTarget ( "http://media09.vbox7.com/s/21/21bbc2dca3r3634e3389.mp4");
dl.download ();
// Quit when the download is done.
// QObject :: connect (& dl, SIGNAL (done ()), & app, SLOT (quit ()));
return a.exec ();
}
and I want to run in the method MainWindow - example:
// mainwindow.cpp
MainWindow :: MainWindow (QWidget * parent):
QMainWindow (parent),
ui (new Ui :: MainWindow)
{
QtDownload dl;
dl.setTarget ( "http://media09.vbox7.com/s/21/21bbc2dca3r3634e3389.mp4");
dl.download ();
// Quit when the download is done.
// QObject :: connect (& dl, SIGNAL (done ()), & app, SLOT (quit ()));
........
}
Here is the current code of the program.
// downloader.pro
#-------------------------------------------------
#
# Project created by QtCreator 2017-01-12T15:22:17
#
#-------------------------------------------------
QT += core gui
QT += network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = downloader
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QObject>
#include <QString>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
class QtDownload : public QObject {
Q_OBJECT
public:
explicit QtDownload();
QNetworkAccessManager manager;
QString target;
void setTarget(const QString& t);
private:
signals:
void done();
public slots:
void download();
void downloadFinished(QNetworkReply* data);
void downloadProgress(qint64 recieved, qint64 total);
};
#endif // MAINWINDOW_H
//main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QtCore>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QUrl>
#include <QtNetwork/QNetworkRequest>
#include <QFile>
#include <QDebug>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkReply>
#include <QByteArray>
#include <QObject>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// QCoreApplication app(argc, argv);
QtDownload dl;
dl.setTarget("http://media09.vbox7.com/s/21/21bbc2dca3r3634e3389.mp4");
dl.download();
//quit when the download is done.
// QObject::connect(&dl, SIGNAL(done()), &app, SLOT(quit()));
}
MainWindow::~MainWindow()
{
delete ui;
}
QtDownload::QtDownload() : QObject(0) {
QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(downloadFinished(QNetworkReply*)));
}
void QtDownload::setTarget(const QString &t) {
this->target = t;
}
void QtDownload::downloadFinished(QNetworkReply *data) {
QFile localFile("C:/downloadedfile.mp4");
if (!localFile.open(QIODevice::WriteOnly))
return;
const QByteArray sdata = data->readAll();
localFile.write(sdata);
qDebug() << sdata;
localFile.close();
emit done();
}
void QtDownload::download() {
QUrl url = QUrl::fromEncoded(this->target.toLocal8Bit());
QNetworkRequest request(url);
QObject::connect(manager.get(request), SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
}
void QtDownload::downloadProgress(qint64 recieved, qint64 total) {
qDebug() << recieved << total;
}
I have tried your code, I had the same problem that you report, only change the creation of the object to a pointer and magically arranged, I still do not understand the reason for error, I will continue to search for reason.
You must be:
...
ui->setupUi(this);
QtDownload *dl = new QtDownload();
dl->setTarget( "http://media09.vbox7.com/s/21/21bbc2dca3r3634e3389.mp4");
dl->download();
...
So.. if you want to run the download at QMainWindowthe object QtDownload dl should be a pointer property of MainWindow or it will not be destroyed (unless dl, as a QObject, hasMainWindow` as parent).
Run it into main() function does not work in this case because the application will run when exec() was called, so the download
So it will be something like this:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
// Delete the `dl` object
~MainWindow() { delete dl; }
private:
Ui::MainWindow *ui;
QtDownload *dl; // Declare it here
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
dl(nullptr)
{
ui->setupUi(this);
// QCoreApplication app(argc, argv);
dl = new QtDownload();
dl->setTarget("http://media09.vbox7.com/s/21/21bbc2dca3r3634e3389.mp4");
dl->download();
// connect the signal `done()` to save the file or anything like that
QObject::connect(dl, SIGNAL(done()), this, SLOT(downloadFinished()));
}
Related
Using QTCreator, I created the design of a GUI Application. I want to read the input entered by the user from lineEdit and when pushButton is clicked, it should print the factorial of that entered number on the same page. I've read some tutorials but don't understand how to code this using qtc++.
A minimal example is like that:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QHBoxLayout>
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void hClicked();
void hTextEdit(const QString& data);
private:
QString m_linedata;
QPushButton button;
QLineEdit lineEdit;
QHBoxLayout layout;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <iostream>
MainWindow::MainWindow(QWidget *parent)
: QWidget(parent)
{
layout.addWidget(&lineEdit);
layout.addWidget(&button);
this->setLayout(&layout);
connect(&lineEdit, &QLineEdit::textChanged, this, &MainWindow::hTextEdit);
connect(&button, &QPushButton::clicked, this , &MainWindow::hClicked);
}
MainWindow::~MainWindow()
{
}
static unsigned factorial(unsigned n)
{
unsigned result = 1;
for (unsigned i=1; i <= n; i++) {
result *= i;
}
return result;
}
void MainWindow::hClicked()
{
if (m_linedata.size() > 0) {
bool res ;
int toint = m_linedata.toInt(&res);
if (res) {
unsigned fact_result = factorial(toint);
lineEdit.clear();
lineEdit.setText(QString::number(fact_result)); }
}
}
void MainWindow::hTextEdit(const QString &data)
{
m_linedata = data;
}
and main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Just do anything you like with the data passed to the auxillary buffer.
Step1: modify the right click menue
Step2: Qt program coding
// main.cpp
int main(int argc, char *argv[])
{
// QSharedMemory shared("Lakers");
// if(shared.attach()) {
// return 0;
// }
// shared.create(1);
QApplication a(argc, argv);
MainWindow w;
w.show();
w.showMainInputParas(argc, argv);
return a.exec();
}
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void showMainInputParas(int argc, char *argv[]);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#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::showMainInputParas(int argc, char *argv[])
{
for(int i=0; i<argc; i++) {
ui->textEdit->append(QString("%1: %2")
.arg(i)
.arg(QString::fromLocal8Bit(argv[i])));
}
}
Step3: select 2 files and open
Step4: show the 2 file paths in single program(wrong)
I want the 2 paths showed in one single program, and I add QSharememory class in main.cpp, but I still do not know how to pass the 2 file paths into main's argc & argv
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I have a problem with accessing progressBar from another class.
Here's the method that does not work.
I have progress bar in UI(mainwindow.ui) with name progressBar.
void QtDownload::downloadProgress(qint64 recieved, qint64 total) {
ui->progressBar->setMaximum(total);
ui->progressBar->setValue(recieved);
}
Here are all parts of the code:
downloader.pro
#-------------------------------------------------
#
# Project created by QtCreator 2017-01-12T15:22:17
#
#-------------------------------------------------
QT += core gui
QT += network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = downloader
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QObject>
#include <QString>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
class QtDownload : public QObject {
Q_OBJECT
public:
explicit QtDownload();
QNetworkAccessManager manager;
QString target;
void setTarget(const QString& t);
private:
signals:
void done();
public slots:
void download();
void downloadFinished(QNetworkReply* data);
void downloadProgress(qint64 recieved, qint64 total);
};
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QtCore>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QUrl>
#include <QtNetwork/QNetworkRequest>
#include <QFile>
#include <QDebug>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkReply>
#include <QByteArray>
#include <QObject>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// QCoreApplication app(argc, argv);
QtDownload *dl = new QtDownload();
dl->setTarget( "http://media09.vbox7.com/s/21/21bbc2dca3r3634e3389.mp4");
dl->download();
//quit when the download is done.
// QObject::connect(&dl, SIGNAL(done()), &app, SLOT(quit()));
}
MainWindow::~MainWindow()
{
delete ui;
}
QtDownload::QtDownload() : QObject(0) {
QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(downloadFinished(QNetworkReply*)));
}
void QtDownload::setTarget(const QString &t) {
this->target = t;
}
void QtDownload::downloadFinished(QNetworkReply *data) {
QFile localFile("C:/downloadedfile.mp4");
if (!localFile.open(QIODevice::WriteOnly))
return;
const QByteArray sdata = data->readAll();
localFile.write(sdata);
qDebug() << sdata;
localFile.close();
emit done();
}
void QtDownload::download() {
QUrl url = QUrl::fromEncoded(this->target.toLocal8Bit());
QNetworkRequest request(url);
QObject::connect(manager.get(request), SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
}
void QtDownload::downloadProgress(qint64 recieved, qint64 total) {
ui->progressBar->setMaximum(total); // DOES NOT WORK
ui->MainWindow.progressBar->setValue(recieved); // DOES NOT WORK
}
That's because your slot shouldn't be inside the QtDownload, it should be inside the MainWindow.
You should pass the MainWindow inside its constructor (just as a parent widget), and reuse this MainWindow in your connect, instead of uthing this.
Edits in your QtDownload :
Header
QtDownload(QObject* parent = 0); //Don't forget to make it in the source file
signals:
void done();
void downloadProgress(qint64 recieved, qint64 total);
public slots:
void download();
void downloadFinished(QNetworkReply* data);
private:
MainWindow* parent; //Set it in the new constructor
Source
QtDownload::QtDownload(QObject *parent) : QObject(parent)
{
//The code that was initially inside QtDownload::QtDownload()
}
void QtDownload::download() {
QUrl url = QUrl::fromEncoded(this->target.toLocal8Bit());
QNetworkRequest request(url);
QObject::connect(manager.get(request), SIGNAL(downloadProgress(qint64,qint64)), parent, SLOT(downloadProgress(qint64,qint64)));
}
Edits in your MainWindow
Header
public slots:
void downloadProgress(qint64 recieved, qint64 total);
Source
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// QCoreApplication app(argc, argv); (Remove this line, it should be in the main.cpp
QtDownload *dl = new QtDownload(this); //Pass this as parameter
dl->setTarget( "http://media09.vbox7.com/s/21/21bbc2dca3r3634e3389.mp4");
dl->download();
//quit when the download is done.
// QObject::connect(&dl, SIGNAL(done()), &app, SLOT(quit()));
}
void MainWindow::downloadProgress(qint64 recieved, qint64 total) {
ui->progressBar->setMaximum(total);
ui->progressBar->setValue(recieved);
}
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);
}
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();
}