Retrieve all the file paths from a QDropEvent - qt

I implemented drag and drop in my software. Basically I've got a QTableView which contains file paths. The user must be able to just drag and drop files in the QTableView in order to add them.
I've already done the big of the job but I'm stuck in iterating all the paths contained in the QDropEvent object. I have to implement the dropEvent method.
void Generous::dropEvent(QDropEvent *dropEvent) {
QStringList filePathList;
// Way to iterate dropEvent and append each file path to filePathList.
addFilesToListView(filePathList);
}
How can I do that?

I would guess that a drag and drop using filepaths use the MIME type text/uri-list.
If this is true, you should probably be able to retrieve the data like this:
if (dropEvent->mimeData()->hasUrls())
{
foreach (QUrl url, dropEvent->mimeData()->urls())
{
filePathList << url.toLocalFile();
}
}
Anyway, since I am not sure, the best would be first to check what kind of info is stored inside the drop event, and see where and how you can extract the filepaths:
QStringList availableMimeTypes = dropEvent->mimeData()->formats();
qDebug() << "available MIME types:" << dropEvent->mimeData()->formats() << "\n";
foreach(QString mimeType, availableMimeTypes)
{
qDebug() << "data for MIME type" << mimeType << " :";
qDebug() << dropEvent->mimeData()->data(mimeType) << "\n";
}

You can also create a global list that will keep appending the filePaths on each dropevent. So at the end you will be having a complete list of paths.

Related

No query Unable to fetch row

I'm attempting to write a piece of code that would get selected item from QTableView and delete it from database.
QModelIndex index = ui->tableView->selectionModel()->currentIndex();
QString value= ui->tableView->model()->data(index).toString();
qDebug() << "Value : " << value;
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("TestDatabase.db");
if(!db.open())
{
qDebug() << db.lastError();
qFatal("Failed to connect");
}
QSqlQuery qry;
qry.prepare("DELETE * FROM movies WHERE Title='"+value+"'");
if(!qry.exec())
{
QMessageBox::critical(this, tr("error::") , qry.lastError().text());
}
db.close();
However, I'm getting 'No query Unable to fetch row' error. I would really appreciate it if you could help me out with that.
Update : The issue was that I placed '*' after DELETE.
Your code suffers form SQL injection since you are using prepare() not correctly. This is also the reason why you get the error. To use prepare() the right way it must be followed by at least one bindValue(). In your case something like:
QSqlQuery qry;
qry.prepare("DELETE * FROM movies WHERE Title = :title");
qry.bindValue(":title", value);
if(!qry.exec()) //...
bindValue() takes care that value is escaped properly and doesn't do any harm.
...if you think that SQL injections aren't a problem, have a chat with Bobby Tables :)

QT 5.5 - QNetworkReply empty data

I already took at others questions but I didn't find an answer.
I have a problem to print HTML code I download with a QNetworkAccessManager.
I need to log into a website to retrieve this code.
I have a slot like this:
void Aims::slotRequestFinished(QNetworkReply* requestReply)
{
QString data = QString(requestReply->readAll());
qDebug() << data;
}
For the first two steps (connection), I can see the HTML code in the console.
The last step doesn't get any data. There is no redirection nor error.
Now, the stranger part is that when I change my code to show the page into a webview, qDebug doesn't show anything, but the code loaded is shown correctly in the webview.
void Aims::slotRequestFinished(QNetworkReply* requestReply)
{
QString data = QString(requestReply->readAll());
qDebug() << data;
ui->webView->setHtml(data);
}
Well, I can save the content into a file. But I would really like to understand why I can't see anything in qDebug

Using QHttpMultiPart with QHttpPart Binary and Form Data

I wrote a method to send a image and some form data to a Django Rest Framework Server. The following method works fine, but I would like to know if there is a way to send the form fields together in one QHttpPart, instead of creating one for each field?
Is there a better way to do this? Maybe with less code?
void MyNetwork::sendBinaryFile() {
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyfinished(QNetworkReply*)));
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart aluno, palavra_chave, latitude, latitude_ref, longitude, longitude_ref;
aluno.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"aluno\""));
aluno.setBody("some useful string");
palavra_chave.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"palavra_chave\""));
palavra_chave.setBody("some other useful string");
latitude.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"latitude\""));
latitude.setBody("0");
longitude.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"longitude\""));
longitude.setBody("0");
latitude_ref.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"latitude_ref\""));
latitude_ref.setBody("N");
longitude_ref.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"longitude_ref\""));
longitude_ref.setBody("E");
multiPart->append(aluno);
multiPart->append(palavra_chave);
multiPart->append(latitude);
multiPart->append(latitude_ref);
multiPart->append(longitude);
multiPart->append(longitude_ref);
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; filename=\"image.png\"; name=\"file\""));
QFile *file = new QFile("/path/image.png");
file->open(QIODevice::ReadOnly);
imagePart.setBodyDevice(file);
file->setParent(multiPart);
multiPart->append(imagePart);
QString sendPath = "http://localhost/api/images/";
QUrl url(sendPath);
QNetworkRequest request(url);
QString concatenated = "username:password";
QByteArray data = "Basic ";
data.append(concatenated.toLocal8Bit().toBase64());
request.setRawHeader("Authorization", data);
manager->post(request,multiPart);
}
void MyNetwork::replyfinished(QNetworkReply* reply)
{
qDebug() << "C++ - replyUpdateJsonFinished";
qDebug() << QString(reply->readAll());
qDebug() << QString(reply->errorString());
}
Because of the nature of multipart/form-data, each field that is sent must be sent in a different part. This is because each part in the request represents a different field, and is identified by the field name and contains the body that should be sent (in your case, mostly text).
You may have better luck creating a helper method for the text field that takes the field name and the content of it. That method would then be able to create a new part with the correct header (containing the field name) and the body (containing the data to send), without requiring you to repeat the same lines.

Checking then Adding items to QCompleter model

I am currently working on a code editor written in Qt,
I have managed to implement most of the features which I desire, i.e. auto completion and syntax highlighting but there is one problem which I can't figure out.
I have created a model for which the QCompleter uses, which is fine for things like html tags and c++ keywords such as if else etc.
But I would like to add variables to the completer as they are entered by the user.
So I created an event on the QTextEdit which will get the word (I know I need to check to make sure that it is a variable etc but I just want to get it working for now).
void TextEdit::checkWord()
{
//going to get the previous word and try to do something with it
QTextCursor tc = textCursor();
tc.movePosition(QTextCursor::PreviousWord);
tc.select(QTextCursor::WordUnderCursor);
QString word = tc.selectedText();
//check to see it is in the model
}
But now I want to work out how to check to see if that word is already in the QCompleters model and if it isn't how do I add it?
I have tried the following:
QAbstractItemModel *m = completer->model();
//dont know what to do with it now :(
You can check if word is in your QCompleter really by using
QAbstractItemModel *m = completer->model();
as you can see, method model() returns const pointer.
That is good for checking procedure, you can check like this:
bool matched = false;
QString etalon("second");
QStringListModel *strModel = qobject_cast<QStringListModel*>(completer.model());
if (strModel!=NULL)
foreach (QString str, strModel->stringList()) {
if (str == etalon)
{
matched = true;
break;
}
}
qDebug()<<matched;
But for your purposes, I recommend you to declare QStringListModel, and connect it to your completer, and then, all of operations you'll must do thru your model, according to Qt's principles of MVC programming (http://doc.qt.digia.com/qt/model-view-programming.html).
Your code can be like this:
// declaration
QCompleter completer;
QStringListModel completerModel;
// initialization
completer.setModel(&completerModel);
QStringList stringListForCompleter;
stringListForCompleter << "first" << "second" << "third";
completerModel.setStringList(stringListForCompleter);
// adding new word to your completer list
completerModel.setStringList(completerModel.stringList() << "New Word");
Good luck!

How to accept Drag and Drop from QListWidget in custom QTextEdit

In my own TextEdit (inherits QTextEdit) I implement this DragEventHandler:
void CustomTextEdit::dragEnterEvent(QDragEnterEvent* e)
{
qDebug() << "void CustomTextEdit::dragEnterEvent(QDragEnterEvent* e)";
qDebug() << "e->mimeData()->hasText() is" << e->mimeData()->hasText();
QTextEdit::dragEnterEvent(e);
}
Example: When I select text inside the TextEdit and drag it around,
the handler gets called and hasText() is true.
When I drag an item from a QListWidget into the TextEdit the handler also gets called
but hasText() is false. How can I handle the DropEvent anyway?
(QDragEnterEvent basically IS a QDropEvent)
I know that this would be done in the DropHandler but my question is
what information does the DropEvent coming from QListWidget contain?
How can access this information?
You can ask a QDragEnterEvent which formats of mime data it contains using QMimeData::formats().
For example:
const QMimeData *mimeData = e->mimeData();
QStringList mimeFormats = mimeData->formats();
foreach(QString format, mimeFormats)
qDebug() << format;
From this we can see that the event's mimeData has the format application/x-qabstractitemmodeldatalist.
The data of any particular format can be retrieved with QMimeData::data(QString mimeType), though in the case of application/x-qabstractitemmodeldatalist, the data is encoded in a pretty specific way. This previous SO question covers decoding the data from the QByteArray returned by QMimeData::data: How to decode "application/x-qabstractitemmodeldatalist" in Qt for drag and drop?

Resources