How can I update my QTableWidget? - c++

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());
}

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.

capture QVideoFrame and display it in QVideoWidget

I want capture from camera frames.
I setup ui, camera, and surface.
QtVideoWidgetsIssueTrack::QtVideoWidgetsIssueTrack(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
QCamera* mCamera = new QCamera();
QMediaRecorder* recorder = new QMediaRecorder(mCamera);
QVideoEncoderSettings settings = recorder->videoSettings();
QMyAbstractVideoSurface* surface = new QMyAbstractVideoSurface();
settings.setResolution(640, 480);
settings.setQuality(QMultimedia::VeryHighQuality);
settings.setFrameRate(30.0);
settings.setCodec("video/mp4");
recorder->setVideoSettings(settings);
recorder->setContainerFormat("mp4");
mCamera->setCaptureMode(QCamera::CaptureViewfinder);
mCamera->setViewfinder(surface);
// Set layout
QGridLayout* layout = new QGridLayout();
QVideoWidget* videoWidget = new QVideoWidget;
videoWidget->show();
// Set layout in QWidget
QWidget* window = new QWidget();
layout->addWidget(videoWidget);
window->setLayout(layout);
// Set QWidget as the central layout of the main window
setCentralWidget(window);
bool o = recorder->setOutputLocation(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/" + "test_video"));
recorder->record();
mCamera->start();
qDebug() << o;
qDebug() << recorder->supportedVideoCodecs();
qDebug() << recorder->state();
qDebug() << recorder->error();
qDebug() << recorder->outputLocation();
}
QtVideoWidgetsIssueTrack::~QtVideoWidgetsIssueTrack()
{}
I have created QMyAbstractVideoSurface instance and set surface in camera.
#pragma once
#include <QtMultimedia/QAbstractVideoSurface>
class QMyAbstractVideoSurface : public QAbstractVideoSurface
{
Q_OBJECT
public:
explicit QMyAbstractVideoSurface(QObject* parent = 0);
~QMyAbstractVideoSurface();
QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const;
bool present(const QVideoFrame& frame);
bool start(const QVideoSurfaceFormat& format);
void stop();
};
Now the problem is capture QVideoFrame from present method and display it in QVideoWidget.
Then add QVideoWidget to grid layout.
#include "QMyAbstractVideoSurface.h"
#include <QDebug>
#include <QBuffer>
QMyAbstractVideoSurface::QMyAbstractVideoSurface(QObject* parent) {
}
bool QMyAbstractVideoSurface::start(const QVideoSurfaceFormat& format) {
return QAbstractVideoSurface::start(format);
}
void QMyAbstractVideoSurface::stop() {
QAbstractVideoSurface::stop();
}
bool QMyAbstractVideoSurface::present(const QVideoFrame& frame) {
if (frame.isValid()) {
QVideoFrame cloneFrame(frame);
QAbstractVideoBuffer::HandleType handleType;
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
qDebug() << cloneFrame;
const QImage image(cloneFrame.bits(),
cloneFrame.width(),
cloneFrame.height(),
QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat()));
QByteArray ba;
QBuffer bu(&ba);
//bu.open(QBuffer::ReadWrite);
bu.open(QIODevice::WriteOnly);
image.save(&bu, "PNG");
//bu.close();
//QString imgBase64 = ba.toBase64();
QString imgBase64 = QString::fromLatin1(ba.toBase64().data());
qDebug() << "image base64: " << imgBase64;
cloneFrame.unmap();
return true;
}
return true;
}
QList<QVideoFrame::PixelFormat> QMyAbstractVideoSurface::
supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
Q_UNUSED(handleType);
return QList<QVideoFrame::PixelFormat>()
<< QVideoFrame::Format_ARGB32
<< QVideoFrame::Format_ARGB32_Premultiplied
<< QVideoFrame::Format_RGB32
<< QVideoFrame::Format_RGB24
<< QVideoFrame::Format_RGB565
<< QVideoFrame::Format_RGB555
<< QVideoFrame::Format_ARGB8565_Premultiplied
<< QVideoFrame::Format_BGRA32
<< QVideoFrame::Format_BGRA32_Premultiplied
<< QVideoFrame::Format_BGR32
<< QVideoFrame::Format_BGR24
<< QVideoFrame::Format_BGR565
<< QVideoFrame::Format_BGR555
<< QVideoFrame::Format_BGRA5658_Premultiplied
<< QVideoFrame::Format_AYUV444
<< QVideoFrame::Format_AYUV444_Premultiplied
<< QVideoFrame::Format_YUV444
<< QVideoFrame::Format_YUV420P
<< QVideoFrame::Format_YV12
<< QVideoFrame::Format_UYVY
<< QVideoFrame::Format_YUYV
<< QVideoFrame::Format_NV12
<< QVideoFrame::Format_NV21
<< QVideoFrame::Format_IMC1
<< QVideoFrame::Format_IMC2
<< QVideoFrame::Format_IMC3
<< QVideoFrame::Format_IMC4
<< QVideoFrame::Format_Y8
<< QVideoFrame::Format_Y16
<< QVideoFrame::Format_Jpeg
<< QVideoFrame::Format_CameraRaw
<< QVideoFrame::Format_AdobeDng;
}
QMyAbstractVideoSurface::~QMyAbstractVideoSurface()
{}
it display me this
QVideoFrame(QSize(640, 480), Format_YUYV, NoHandle, ReadOnly, [no timestamp])
image base64: ""

Refresh QTableWidget automatically possible?

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.

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.