Refresh QTableWidget automatically possible? - c++

QTableWidget(in my code, ipTable) Item come from test_data.txt.
But test_data.txt file change in every 3seconds.
I want refresh the table automatically..
How can I update QTableWidget automatically..?
This is my code.
#include "dialog.h"
#include "ui_dialog.h"
#include "addip.h"
#include <QFile>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));
timer->start(1000);
setWindowTitle( "IP List" );
ui->ipTable->setColumnCount(3);
refresh_table();
}
Dialog::~Dialog()
{
delete ui;
}
QStringList Dialog::refresh_table()
{
int field;
QFile file( "/home/yein/widget/test_data.txt" );
QStringList title;
title << "IP" << "Protocol" << "state";
file.open( QIODevice::ReadOnly);
QTextStream read(&file);
ui->ipTable->clear();
ui->ipTable->setRowCount(0);
ui->ipTable->setHorizontalHeaderLabels(title);
while(!read.atEnd())
{
QString tmp = read.readLine();
QStringList tmpList = tmp.split( "," );
ui->ipTable->insertRow(ui->ipTable->rowCount());
field = ui->ipTable->rowCount() - 1;
ui->ipTable->setItem( field, IP, new QTableWidgetItem( tmpList[0] ) );
ui->ipTable->setItem( field, PROTOCOL, new QTableWidgetItem( tmpList[1] ) );
ui->ipTable->setItem( field, STATE, new QTableWidgetItem( tmpList[2] ) );
}
file.close();
return table;
}
void Dialog::on_btnAdd_clicked()
{
QString protocol;
QString IP;
int res;
addIP add(this);
add.setWindowTitle( "Add IP" );
res = add.exec();
if( res == QDialog::Rejected )
return;
IP = add.getIP();
protocol = add.getProtocol();
qDebug() << "IP :" << " " << IP;
qDebug() << "Protocol : " << " " << protocol;
write_on_file( IP,protocol );
}
void Dialog::write_on_file( QString IP, QString protocol )
{
QFile file( "/home/yein/widget/test_data.txt" );
file.open( QIODevice::Append );
data[0] = IP;
data[1] = protocol;
data[2] = "0"; // init state 0
QString _str = QString( "%1,%2,%3\n" )
.arg( data[0] )
.arg( data[1] )
.arg( data[2] );
qDebug() << _str << " ";
QByteArray str;
str.append(_str);
file.write(str);
file.close();
refresh_table();
}
void Dialog::on_btnClose_clicked()
{
this->close();
}
void Dialog::onTimer()
{
updateRStatusBar();
}
void Dialog::updateRStatusBar()
{
QDateTime local(QDateTime::currentDateTime());
ui->clock->setText(local.toString());
}

One option is to use
QFileSystemWatcher::fileChanged(const QString &path)
and receive a signal, whenever the file is modified. This recommandation depends on how often the file is changed and on how many files you want to watch.

Related

Email not sending when using SMTP server on Qt 4

I've been making a desktop app using Qt 4 and C++.
This is my code:
maiwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->sendBtn, SIGNAL(clicked()),this, SLOT(sendMail()));
connect(ui->exitBtn, SIGNAL(clicked()),this, SLOT(close()));
connect(ui->browseBtn, SIGNAL(clicked()), this, SLOT(browse()));
ui->paswd->setEchoMode(QLineEdit::Password);
}
void MainWindow::browse()
{
files.clear();
QFileDialog dialog(this);
dialog.setDirectory(QDir::homePath());
dialog.setFileMode(QFileDialog::ExistingFiles);
if (dialog.exec())
files = dialog.selectedFiles();
QString fileListString;
foreach(QString file, files)
fileListString.append( "\"" + QFileInfo(file).fileName() + "\" " );
ui->file->setText( fileListString );
}
void MainWindow::sendMail()
{
Smtp* smtp = new Smtp(ui->uname->text(), ui->paswd->text(), ui->server->text(), ui->port->text().toInt());
connect(smtp, SIGNAL(status(QString)), this, SLOT(mailSent(QString)));
if( !files.isEmpty() )
smtp->sendMail(ui->uname->text(), ui->rcpt->text() , ui->subject->text(),ui->msg->toPlainText(), files );
else
smtp->sendMail(ui->uname->text(), ui->rcpt->text() , ui->subject->text(),ui->msg->toPlainText());
}
void MainWindow::mailSent(QString status)
{
if(status == "Message sent")
QMessageBox::warning( 0, tr( "Qt Simple SMTP client" ), tr( "Message sent!\n\n" ) );
}
MainWindow::~MainWindow()
{
delete ui;
}
smtp.cpp
#include "smtp.h"
Smtp::Smtp( const QString &user, const QString &pass, const QString &host, int port, int timeout )
{
socket = new QSslSocket(this);
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
connect(socket, SIGNAL(connected()), this, SLOT(connected() ) );
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this,SLOT(errorReceived(QAbstractSocket::SocketError)));
connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(stateChanged(QAbstractSocket::SocketState)));
connect(socket, SIGNAL(disconnected()), this,SLOT(disconnected()));
this->user = user;
this->pass = pass;
this->host = host;
this->port = port;
this->timeout = timeout;
}
void Smtp::sendMail(const QString &from, const QString &to, const QString &subject, const QString &body, QStringList files)
{
message = "To: " + to + "\n";
message.append("From: " + from + "\n");
message.append("Subject: " + subject + "\n");
//Let's intitiate multipart MIME with cutting boundary "frontier"
message.append("MIME-Version: 1.0\n");
message.append("Content-Type: multipart/mixed; boundary=frontier\n\n");
message.append( "--frontier\n" );
//message.append( "Content-Type: text/html\n\n" ); //Uncomment this for HTML formating, coment the line below
message.append( "Content-Type: text/plain\n\n" );
message.append(body);
message.append("\n\n");
if(!files.isEmpty())
{
qDebug() << "Files to be sent: " << files.size();
foreach(QString filePath, files)
{
QFile file(filePath);
if(file.exists())
{
if (!file.open(QIODevice::ReadOnly))
{
qDebug("Couldn't open the file");
QMessageBox::warning( 0, tr( "Qt Simple SMTP client" ), tr( "Couldn't open the file\n\n" ) );
return ;
}
QByteArray bytes = file.readAll();
message.append( "--frontier\n" );
message.append( "Content-Type: application/octet-stream\nContent-Disposition: attachment; filename="+ QFileInfo(file.fileName()).fileName() +";\nContent-Transfer-Encoding: base64\n\n" );
message.append(bytes.toBase64());
message.append("\n");
}
}
}
else
qDebug() << "No attachments found";
message.append( "--frontier--\n" );
message.replace( QString::fromLatin1( "\n" ), QString::fromLatin1( "\r\n" ) );
message.replace( QString::fromLatin1( "\r\n.\r\n" ),QString::fromLatin1( "\r\n..\r\n" ) );
this->from = from;
rcpt = to;
state = Init;
socket->connectToHostEncrypted(host, port); //"smtp.gmail.com" and 465 for gmail TLS
if (!socket->waitForConnected(timeout)) {
qDebug() << socket->errorString();
}
t = new QTextStream( socket );
}
Smtp::~Smtp()
{
delete t;
delete socket;
}
void Smtp::stateChanged(QAbstractSocket::SocketState socketState)
{
qDebug() <<"stateChanged " << socketState;
}
void Smtp::errorReceived(QAbstractSocket::SocketError socketError)
{
qDebug() << "error " <<socketError;
}
void Smtp::disconnected()
{
qDebug() <<"disconneted";
qDebug() << "error " << socket->errorString();
}
void Smtp::connected()
{
qDebug() << "Connected ";
}
void Smtp::readyRead()
{
qDebug() <<"readyRead";
// SMTP is line-oriented
QString responseLine;
do
{
responseLine = socket->readLine();
response += responseLine;
}
while ( socket->canReadLine() && responseLine[3] != ' ' );
responseLine.truncate( 3 );
qDebug() << "Server response code:" << responseLine;
qDebug() << "Server response: " << response;
if ( state == Init && responseLine == "220" )
{
// banner was okay, let's go on
*t << "EHLO localhost" <<"\r\n";
t->flush();
state = HandShake;
}
//No need, because I'm using socket->startClienEncryption() which makes the SSL handshake for you
/*else if (state == Tls && responseLine == "250")
{
// Trying AUTH
qDebug() << "STarting Tls";
*t << "STARTTLS" << "\r\n";
t->flush();
state = HandShake;
}*/
else if (state == HandShake && responseLine == "250")
{
socket->startClientEncryption();
if(!socket->waitForEncrypted(timeout))
{
qDebug() << socket->errorString();
state = Close;
}
//Send EHLO once again but now encrypted
*t << "EHLO localhost" << "\r\n";
t->flush();
state = Auth;
}
else if (state == Auth && responseLine == "250")
{
// Trying AUTH
qDebug() << "Auth";
*t << "AUTH LOGIN" << "\r\n";
t->flush();
state = User;
}
else if (state == User && responseLine == "334")
{
//Trying User
qDebug() << "Username";
//GMAIL is using XOAUTH2 protocol, which basically means that password and username has to be sent in base64 coding
//https://developers.google.com/gmail/xoauth2_protocol
*t << QByteArray().append(user).toBase64() << "\r\n";
t->flush();
state = Pass;
}
else if (state == Pass && responseLine == "334")
{
//Trying pass
qDebug() << "Pass";
*t << QByteArray().append(pass).toBase64() << "\r\n";
t->flush();
state = Mail;
}
else if ( state == Mail && responseLine == "235" )
{
// HELO response was okay (well, it has to be)
//Apperantly for Google it is mandatory to have MAIL FROM and RCPT email formated the following way -> <email#gmail.com>
qDebug() << "MAIL FROM:<" << from << ">";
*t << "MAIL FROM:<" << from << ">\r\n";
t->flush();
state = Rcpt;
}
else if ( state == Rcpt && responseLine == "250" )
{
//Apperantly for Google it is mandatory to have MAIL FROM and RCPT email formated the following way -> <email#gmail.com>
*t << "RCPT TO:<" << rcpt << ">\r\n"; //r
t->flush();
state = Data;
}
else if ( state == Data && responseLine == "250" )
{
*t << "DATA\r\n";
t->flush();
state = Body;
}
else if ( state == Body && responseLine == "354" )
{
*t << message << "\r\n.\r\n";
t->flush();
state = Quit;
}
else if ( state == Quit && responseLine == "250" )
{
*t << "QUIT\r\n";
t->flush();
// here, we just close.
state = Close;
emit status( tr( "Message sent" ) );
}
else if ( state == Close )
{
deleteLater();
return;
}
else
{
// something broke.
QMessageBox::warning( 0, tr( "Qt Simple SMTP client" ), tr( "Unexpected reply from SMTP server:\n\n" ) + response );
state = Close;
emit status( tr( "Failed to send message" ) );
}
response = "";
}
I wanted to use SMTP server to send emails but i had this error:
No attachments found
stateChanged QAbstractSocket::HostLookupState
stateChanged QAbstractSocket::ConnectingState
stateChanged QAbstractSocket::ConnectedState
qt.network.ssl: QSslSocket: cannot call unresolved function SSLv23_client_method
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_CTX_new
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_library_init
qt.network.ssl: QSslSocket: cannot call unresolved function ERR_get_error
error QAbstractSocket::SocketError(21)
qt.network.ssl: QSslSocket: cannot call unresolved function ERR_get_error
error QAbstractSocket::SocketError(20)
Connected
error QAbstractSocket::RemoteHostClosedError
stateChanged QAbstractSocket::ClosingState
stateChanged QAbstractSocket::UnconnectedState
disconneted
error "The remote host closed the connection"
error QAbstractSocket::RemoteHostClosedError
stateChanged QAbstractSocket::ClosingState "
So basically it connected to my email but didn't send the message and it closed the connection after.
I tried installing OpenSSL and including it to my project but nothing has changed.

Read Json from https in qt

I wrote this code on qt, but when i run this project, My output is "Error".
How can solve my problem?
For example in this code I add a address in url, and I want read Json from this url, and show some info.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QNetworkAccessManager* nam = new QNetworkAccessManager(this);
QString test = "ar";
QString test2 = "Hello World";
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(onResult(QNetworkReply*)));
QUrl url("https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20180627T161429Z.7e64c91dd2016a6c.9901da9a44bc324388a2460776ab55b2d72b4c5a&lang=" + test + "&text=" + test2);
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void MainWindow::onResult(QNetworkReply *reply)
{
if(reply->error() == QNetworkReply::NoError) {
QStringList propertyNames;
QStringList propertyKeys;
QString strReply = (QString)reply->readAll();
qDebug() << strReply;
QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8());
QJsonObject jsonObject = jsonResponse.object();
QJsonArray jsonArray = jsonObject["status"].toArray();
qDebug() << jsonObject["status"].toString();
foreach (const QJsonValue & value, jsonArray)
{
QJsonObject obj = value.toObject();
qDebug() << value.toString();
}
} else {
qDebug() << "ERROR";
}
delete reply;
}
To add key-values ​​to the url you must use QUrlQuery as shown below:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
nam = new QNetworkAccessManager(this);
connect(nam, &QNetworkAccessManager::finished, this, &MainWindow::onResult);
QString lang = "ar";
QString text = "Hello World";
QString key = "trnsl.1.1.20180627T161429Z.7e64c91dd2016a6c.9901da9a44bc324388a2460776ab55b2d72b4c5a";
QUrlQuery query;
query.addQueryItem("key", key);
query.addQueryItem("lang", lang);
query.addQueryItem("text", text);
QUrl url("https://translate.yandex.net/api/v1.5/tr.json/translate");
url.setQuery(query);
qDebug()<< "url: "<< url.toString(QUrl::FullyEncoded);
nam->get(QNetworkRequest(url));
}
void MainWindow::onResult(QNetworkReply *reply){
if(reply->error() == QNetworkReply::NoError){
QByteArray result = reply->readAll();
QJsonDocument jsonResponse = QJsonDocument::fromJson(result);
QJsonObject obj = jsonResponse.object();
qDebug()<<"code: " << obj["code"].toInt();
qDebug()<<"lang: " << obj["lang"].toString();
QJsonArray array = obj["text"].toArray();
for(const QJsonValue & value : array) {
qDebug()<< "text: " <<value.toString();
}
}
else
qDebug() << "ERROR";
reply->deleteLater();
}
Output:
url: "https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20180627T161429Z.7e64c91dd2016a6c.9901da9a44bc324388a2460776ab55b2d72b4c5a&lang=ar&text=Hello%20World"
code: 200
lang: "en-ar"
text: "مرحبا العالم"
If the url generated is revised, it differs from the concatenation:
Concatenation:
...&text=Hello World
Encoded:
...&text=Hello%20World

How can I update my QTableWidget?

I want update my QTableWidget but i can't.
TableWidget data come from file( test_data.txt ).
When I press the add button add "ip & protocol" then the data append test_data.txt
but appened data is not appear in my QTableWidget.
this is my code..
#include "dialog.h"
#include "ui_dialog.h"
#include "addip.h"
#include <QFile>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));
timer->start(1000);
setWindowTitle( "IP List" );
QStringList title;
title << "IP" << "Protocol" << "state";
ui->ipTable->setColumnCount(3);
ui->ipTable->setHorizontalHeaderLabels(title);
refresh_table();
}
Dialog::~Dialog()
{
delete ui;
}
QStringList Dialog::refresh_table()
{
int field;
QFile file( "/home/yein/widget/test_data.txt" );
file.open( QIODevice::ReadOnly);
QTextStream read(&file);
while(!read.atEnd())
{
QString tmp = read.readLine();
QStringList tmpList = tmp.split( " " );
ui->ipTable->insertRow(ui->ipTable->rowCount());
field = ui->ipTable->rowCount() - 1;
ui->ipTable->setItem( field, IP, new QTableWidgetItem( tmpList[0] ) );
ui->ipTable->setItem( field, PROTOCOL, new QTableWidgetItem( tmpList[1] ) );
ui->ipTable->setItem( field, STATE, new QTableWidgetItem( tmpList[2] ) );
}
file.close();
return table;
}
void Dialog::on_btnAdd_clicked()
{
QString protocol;
QString IP;
int res;
addIP add(this);
add.setWindowTitle( "Add IP" );
res = add.exec();
if( res == QDialog::Rejected )
return;
IP = add.getIP();
protocol = add.getProtocol();
qDebug() << "IP :" << " " << IP;
qDebug() << "Protocol : " << " " << protocol;
write_on_file( IP,protocol );
}
void Dialog::write_on_file( QString IP, QString protocol )
{
QFile file( "/home/yein/widget/test_data.txt" );
file.open( QIODevice::Append );
data[0] = IP;
data[1] = protocol;
data[2] = "0"; // init state 0
QString _str = QString( "%1 %2 %3\n" )
.arg( data[0] )
.arg( data[1] )
.arg( data[2] );
qDebug() << _str << " ";
QByteArray str;
str.append(_str);
file.write(str);
file.close();
}
void Dialog::on_btnClose_clicked()
{
this->close();
}
void Dialog::onTimer()
{
updateRStatusBar();
}
void Dialog::updateRStatusBar()
{
QDateTime local(QDateTime::currentDateTime());
ui->clock->setText(local.toString());
}

How to manipulate multiple Folders/Dir in QT?

I want to know how to manipulate directories until I get video files.
Firstly the main Directory is "F:/TestingVideos/"
Inside the test video there are files e.g:1. Cash Office ,2.Rosville Gate ,3. My Videos
Each of this videos holds other folders for example Cash Office has a Directory of "F:/TestingVideos/Cash Office/" inside we have folders that have dates for example we have the following "F:/TestingVideos/Cash Office/20141201/" Inside the Date Folder I have videos that I want to play.
So far I have implemented a method:
void Dialog::on_loadedButton_clicked(){
QString videoname = "F:/TestingVideos/";`
ui->DirectoryLineEdit->setText(videoName);
QDir dir(videoName);
QFileInfoList files = dir.entryInfoList();
QStringList MonTypeFolder = dir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs, QDir::DirsFirst);
ui->MonitoringcomboBox->addItems( MonTypeFolder);
ui->MonitoringcomboBox->show();
foreach(QFileInfo file, files){
if(file.isDir()){
//qDebug() << "DIR: " << file.fileName();
// qDebug() << "Directory path file:" << file.absoluteFilePath();
QString filePathString = file.absoluteFilePath();
QFileInfo info = QFileInfo(filePathString);
qDebug() << "Folders" << " are writable: " << info.isWritable() << "are readable: " << info.isReadable();
}
if(file.isFile()){
qDebug() << "FILE: " << file.fileName();
}
}
my output is true for my QFileInfo info; for writeable and readable, also I do did a qDebug()<< info.absoluteFilePath() I got the following results:
"F:/TestingVideos"
"F:/"
"F:/TestingVideos/Cash Office"
"F:/TestingVideos/Rosville"
"F:/TestingVideos/My Videos"
I want a way to manipulate the baseNames i.e. Cash Office, Rosville etc... Folders such that I can display their folders e.g. 20141201 in another combobox, since currently ui.monitoringcomboBox->show() can display the base names. I want to be able to manipulate the folders basically To a level where I where I can play a video using QUrl for example.
If i understood correctly you want something like this:
My code is a bit rough but you can use it as starting point:
-MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QComboBox>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QComboBox *mainCB_;
QComboBox *baseCB_;
QComboBox *datesCB_;
QComboBox *mediaCB_;
QString path_;
QStringList media_;
void createComboBoxes();
private slots:
void onBaseComboBoxActivated(QString folderText);
void onDatesComboBoxActivated(QString folderText);
void onMediaComboBoxActivated(QString folderText);
};
#endif // MAINWINDOW_H
-MainWindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDir>
#include <QDebug>
#define CBWidth 140
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
media_()
{
ui->setupUi(this);
setFixedSize(840, 400);
path_ = "/Users/its/Desktop/Testing Videos"; //insert your root folder path here
media_ << "*.3gp" << "*.avi" << "*.m4v" << "*.mov" << "*.mp4" << "*.mpeg" << "*.mpg" << "*.3g2" << "*.mxf" << "*.swf" << "*.m2v" << "*.wmv" << "*.flv" << "*.mkv";
QDir dir(path_);
if(dir.exists())
{
createComboBoxes();
}
else
{
qDebug() << "Error: Main dir " << path_ << " doesn't exist.";
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::createComboBoxes()
{
mainCB_ = new QComboBox(this);
mainCB_->addItem(path_.section('/', -1));
mainCB_->setFixedWidth(CBWidth);
mainCB_->move(50, 50);
baseCB_ = new QComboBox(this);
baseCB_->setFixedWidth(CBWidth);
baseCB_->move(250, 50);
datesCB_ = new QComboBox(this);
datesCB_->setFixedWidth(CBWidth);
datesCB_->move(450, 50);
mediaCB_ = new QComboBox(this);
mediaCB_->setFixedWidth(CBWidth);
mediaCB_->move(650, 50);
QDir mainFolderDir(path_);
QStringList mainFolderContent = mainFolderDir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs, QDir::DirsFirst);
baseCB_->addItems(mainFolderContent);
connect(baseCB_, SIGNAL(activated(QString)), this, SLOT(onBaseComboBoxActivated(QString)));
onBaseComboBoxActivated(baseCB_->itemText(0));
connect(datesCB_, SIGNAL(activated(QString)), this, SLOT(onDatesComboBoxActivated(QString)));
connect(mediaCB_, SIGNAL(activated(QString)), this, SLOT(onMediaComboBoxActivated(QString)));
}
void MainWindow::onBaseComboBoxActivated(QString folderText)
{
QDir baseFolderDir(path_ + "/" + folderText);
if(baseFolderDir.exists())
{
QStringList baseFolderContent = baseFolderDir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs, QDir::DirsFirst);
datesCB_->clear();
datesCB_->addItems(baseFolderContent);
onDatesComboBoxActivated(datesCB_->itemText(0));
}
else
{
qDebug() << "Error: Base dir " << path_ + "/" + folderText << " doesn't exist.";
}
}
void MainWindow::onDatesComboBoxActivated(QString datesText)
{
QDir datesFolderDir(path_ + "/" + baseCB_->currentText() + "/" + datesText);
if(datesFolderDir.exists())
{
QStringList datesFolderContent = datesFolderDir.entryList(media_, QDir::Files, QDir::Name);
mediaCB_->clear();
mediaCB_->addItems(datesFolderContent);
onMediaComboBoxActivated(mediaCB_->itemText(0));
}
else
{
qDebug() << "Error: Dates dir " << path_ + "/" + baseCB_->currentText() + "/" + datesText << " doesn't exist.";
}
}
void MainWindow::onMediaComboBoxActivated(QString mediaText)
{
qDebug() << "Media selected with URL:" << path_ + "/" + baseCB_->currentText() + "/" + datesCB_->currentText() + "/" + mediaText;
}
I hope this will help you.

QHttpMultiPart send post request results in "1"

I am currently using QHttpMultiPart in a Qt Project, but it seems to have some problems on my end ?
I have followed the example and came up with the following code:
#include "uploader.h"
#include <QFileInfo>
#include <QMimeDatabase>
#include <QHttpMultiPart>
#include <QNetworkReply>
#include <QDebug>
/**
* #brief Uploader::Uploader
* #param parent
*/
Uploader::Uploader(QObject *parent) :
QObject(parent)
{
uploadInProgress = false;
}
/**
* #brief Uploader::upload
* #param absoluteFilePath
*/
void Uploader::upload(QString absoluteFilePath)
{
qDebug() << "Upload Starting";
QFileInfo fileInfo(absoluteFilePath);
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
//action part
QHttpPart textPart;
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"cmd\""));
textPart.setBody(QString("wFile").toLatin1());
//File Path
QHttpPart filePathPart;
filePathPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file_path\""));
filePathPart.setBody(absoluteFilePath.toLatin1());
//filepart
QHttpPart filePart;
QMimeDatabase db;
QMimeType mime = db.mimeTypeForFile(absoluteFilePath);
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(mime.name()));
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"preview_file\"; filename=\""+ fileInfo.baseName() + "\""));
QFile *file = new QFile(absoluteFilePath);
if ( !file->exists() )
{
qDebug() << "File Does not exist";
}
file->open(QIODevice::ReadOnly);
filePart.setBodyDevice(file);
file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
multiPart->append(textPart);
multiPart->append(filePathPart);
multiPart->append(filePart);
QUrl url("http://project.dbz.dev/index.php?controller=wapi&action=handle");
QNetworkRequest request(url);
pManager = new QNetworkAccessManager();
pReply = pManager->post(request, multiPart);
multiPart->setParent(pReply);
connect(pReply, SIGNAL(uploadProgress(qint64,qint64)),this,SLOT(uploadProgress(qint64,qint64)));
connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
connect(pReply, SIGNAL(finished()),this, SLOT(uploadFinished()));
// here connect signals etc.
uploadInProgress = true;
}
/**
* #brief Uploader::uploadFinished
*/
void Uploader::uploadFinished()
{
QString data = (QString) pReply->readAll();
qDebug() << data;
qDebug() << "Upload finished";
uploadInProgress = false;
if ( pReply->error() > 0 )
{
qDebug() << "Error occured: " << pReply->error() << " : " << pReply->errorString();
}
else
{
qDebug() << "Upload success";
}
delete pReply;
}
void Uploader::uploadProgress(qint64 a, qint64 b)
{
qDebug() << " SOME PROGRESS!";
qDebug() << a << "/" << b;
}
void Uploader::onError(QNetworkReply::NetworkError err)
{
qDebug() << " SOME ERROR!";
qDebug() << err;
}
Sadly, none of the SLOTS are triggered from the SIGNALS. Neither can I see a package send with wireshark on my local ethernet adapter.
However, my Apache does get a request:
192.168.178.21 - - [21/Sep/2013:05:10:41 +0200] "POST /index.php?controller=wapi&action=handle HTTP/1.1" 200 166 "-" "Mozilla/5.0"
And in my PHP Application I have the following outcome:
Application_Controller_WapiController::handleAction: Command: wFile
Application_Controller_WapiController::wFile: POST Request: 1
This, basically means, it recognises the Parameter "cmd" and the value "wFile", opens the according PHP action which then does a print_r($_POST) which shows me nothing more than a simple 1.
I have no idea what to do. I have looked everywhere on the internet and cannot seem to figure it out. I followed all examples and descriptions on the official documentary and found a couple of threads here on SO. There seemed to be a bug with the QHttpMultiPart class, although it was fixed with the major 5.0.0 update.
tl;dr:
connect(pReply, SIGNAL(uploadProgress(qint64,qint64)),this,SLOT(uploadProgress(qint64,qint64)));
connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
connect(pReply, SIGNAL(finished()),this, SLOT(uploadFinished()));
These signals are not being triggered, PHP print_r shows me a 1 and I cannot track the POST request on my machine.
It would be nice if somebody could tell me why the SIGNALS are not emitted and more importantly how I can see a final version of my POST request in my C++ application before it is sent.
Thank you very much! I appreciate any help!
I have solved the problem by adding:
pELoop = new QEventLoop();
pELoop->exec();
Which results into this:
#include "uploader.h"
#include <QFileInfo>
#include <QMimeDatabase>
#include <QHttpMultiPart>
#include <QNetworkReply>
#include <QDebug>
/**
* #brief Uploader::Uploader
* #param parent
*/
Uploader::Uploader(QObject *parent) :
QObject(parent)
{
uploadInProgress = false;
}
/**
* #brief Uploader::upload
* #param absoluteFilePath
*/
void Uploader::upload(QString absoluteFilePath)
{
qDebug() << "Upload Starting";
QFileInfo fileInfo(absoluteFilePath);
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
//action part
QHttpPart textPart;
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"cmd\""));
textPart.setBody(QString("wFile").toLatin1());
//File Path
QHttpPart filePathPart;
filePathPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file_path\""));
filePathPart.setBody(absoluteFilePath.toLatin1());
//filepart
QHttpPart filePart;
QMimeDatabase db;
QMimeType mime = db.mimeTypeForFile(absoluteFilePath);
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(mime.name()));
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"preview_file\"; filename=\""+ fileInfo.baseName() + "\""));
QFile *file = new QFile(absoluteFilePath);
if ( !file->exists() )
{
qDebug() << "File Does not exist";
}
file->open(QIODevice::ReadOnly);
filePart.setBodyDevice(file);
file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
multiPart->append(textPart);
multiPart->append(filePathPart);
multiPart->append(filePart);
QUrl url("http://encryptor.dbz.dev/index.php?controller=wapi&action=handle");
QNetworkRequest request(url);
pManager = new QNetworkAccessManager();
pReply = pManager->post(request, multiPart);
multiPart->setParent(pReply);
pELoop = new QEventLoop();
connect(pReply, SIGNAL(uploadProgress(qint64,qint64)),this,SLOT(uploadProgress(qint64,qint64)));
connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
connect(pReply, SIGNAL(finished()),this, SLOT(uploadFinished()));
pELoop->exec();
// here connect signals etc.
uploadInProgress = true;
}
/**
* #brief Uploader::uploadFinished
*/
void Uploader::uploadFinished()
{
QString data = (QString) pReply->readAll();
qDebug() << data;
qDebug() << "Upload finished";
uploadInProgress = false;
if ( pReply->error() > 0 )
{
qDebug() << "Error occured: " << pReply->error() << " : " << pReply->errorString();
}
else
{
qDebug() << "Upload success";
}
pReply->deleteLater();
pELoop->exit();
}
void Uploader::uploadProgress(qint64 a, qint64 b)
{
qDebug() << " SOME PROGRESS!";
qDebug() << a << "/" << b;
}
void Uploader::onError(QNetworkReply::NetworkError err)
{
qDebug() << " SOME ERROR!";
qDebug() << err;
}
The request is executed as expected, and the signals are working as well.
I get the output of:
Upload Starting
SOME PROGRESS!
16384 / 483753
SOME PROGRESS!
483753 / 483753
SOME PROGRESS!
0 / 0
"Array
(
[controller] => wapi
[action] => handle
[cmd] => wFile
[file_path] => D:/Downloads/putty.exe
)
{"cmd":"","status":"","message":"","params":[]}"
Upload finished
Upload success
I leave this hear in case somebody is looking for a working example.