How to connect a Button to FileDialog function in ubuntu sdk? - c++

I've just started to deploy my first application for Ubuntu using QtCreator 3.1.1 based on Qt5.2.1 on Ubuntu 14.10.. I need to open some video files, so I'm going to put a Button to choose file obviously. Also I know I can use this function to open files:
FileDialog {
id: fileDialog
title: "Please choose a file"
onAccepted: {
console.log("You chose: " + fileDialog.fileUrls)
Qt.quit()
}
onRejected: {
console.log("Canceled")
Qt.quit()
}
Component.onCompleted: visible = true
}
Here's my question: How can I connect them to each other? I want the FielDialog to be opened when I click on the button. And is that the only way to do this? I mean couldn't I do the same process in C++ code?

Of course you can do in C++.
There's a Qt class called QFileDialog: http://qt-project.org/doc/qt-5/QFileDialog.html
You can simply connect a button clicked signal to a slot that creates a QFileDialog, you can use some of the static functions like in the example:
fileName = QFileDialog::getOpenFileName(this,
tr("Open Image"), "/home/jana", tr("Image Files (*.png *.jpg *.bmp)"));
and here how to use the QPushButton: http://qt-project.org/wiki/How_to_Use_QPushButton

Related

Why does the QMessageBox opened from QFileDialog::accept() does not stay on top on macOS?

I try to have with Qt a file dialog, which asks the user for confirmation if the chosen file does not exist. So basically the same you get with the Windows API via IFileDialog::SetOptions(FOS_CREATEPROMPT).
So I derived a new class from QFileDialog to overwrite QFileDialog::accept().
The new QFileDialogEx::accept() opens a QMessageBox when the user clicks on Open, but the file does not exist. If the user chooses "No", the file dialog will not be accepted and keeps open.
That works fine on Linux, but on macOS, the QMessageBox does not stay on top of the QFileDialog. So if the user clicks on the QFileDialog under the QMessageBox, it will come to the top, hiding the QMessageBox.
Here is my code:
class QFileDialogEx : public QFileDialog
{
public:
QFileDialogEx(QWidget *parent, const QString &caption, const QString &directory)
: QFileDialog(parent, caption, directory) {
this->setOption(QFileDialog::DontUseNativeDialog);
}
void accept(void) {
QString selectedFilePath = this->selectedFiles().value(0);
QFileInfo selectedFileInfo(selectedFilePath);
if (!selectedFileInfo.exists()) {
// File does not exist => Ask if file should be created
QMessageBox msgBox(this);
msgBox.setWindowFlags(msgBox.windowFlags() | Qt::WindowStaysOnTopHint);
msgBox.setText(selectedFileInfo.fileName() + "\nThis file doesn't exist.\n\nDo you want to create this file?");
msgBox.setWindowTitle("Create Prompt");
msgBox.setIcon(QMessageBox::Warning);
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes);
if (msgBox.exec() == QMessageBox::No)
return; // Keep file dialog open
}
QFileDialog::accept();
}
};
I've searched a lot about keeping a QMessageBox box on top. Normally the point is: "Set the parent". But as you can see, I did that already. I also desperately tried Qt::WindowStaysOnTopHint and msgBox.setWindowModality(Qt::ApplicationModal) without success.
Just to be clear: I am not using the native file dialogs here. (QFileDialog::DontUseNativeDialogs)
Any idea how to let the QMessageBox stay on top of the QFileDialog also on macOS?
Or any other idea, on how to implement a prompt when the user clicks on Open, but the chosen file does not exist?

Qt::QFileDialog crashes my application when called a second time

I am very new to Qt and OpenCV and am creating a project integrating both. The problem I am running into is that I have a button to load a file, which uses QFileDialog. The whole thing runs smoothly and my file gets loaded. However, it crashes if I click the load button a second time. It seems like the problem occurs at the call to QFileDialog::getOpenFileName, but I need an expert opinion.
This is the function for the button click.
void MainWindow::on_pushButton_clicked()
{
QFileDialog dialog(this);
dialog.setNameFilter(tr("Images (*.png *.xpm *.jpg)"));
dialog.setViewMode(QFileDialog::Detail);
// dialog.setAttribute(Qt::WA_DeleteOnClose);
// dialog.DontUseNativeDialog;
filename = QFileDialog::getOpenFileName(this, tr("Open File"),
"/home",
tr("Images (*.png *.xpm *.jpg)"));
imageObject = new QImage();
imageObject->load(filename);
image = QPixmap::fromImage(*imageObject);
scene = new QGraphicsScene(this);
scene->addPixmap(image);
scene->setSceneRect(image.rect());
ui->graphicsView->setScene(scene);
ui->graphicsView->fitInView(scene->sceneRect(),Qt::KeepAspectRatio);
cvHandler = new OpenCVHandler(filename.toStdString());
}
I have already tried both the lines that are commented out. My search also turned up nothing that I could understand easily:
Crash when calling getOpenFileName from QItemDelegate's custom editor
QFileDialog opens a second (possibly parent) unwanted window
Qt File Dialog Rendered Incorrectly and Crashes
If at all relevant, I am on an Ubuntu 16.04 LTS system.
Thank you
The problem was in the commented lines. I didn't use dialog.DontUseNativeDialog properly. Using it inside the getOpenFileName function did the trick:
filename = QFileDialog::getOpenFileName(this, tr("Open File"),
"/home",
tr("Images (*.png *.xpm *.jpg)"),0,QFileDialog::DontUseNativeDialog);
Thank you all.

OpenFileDialog freez in QT creator

When I open an open file dialog the first time everything works as it should, meaning the dialog opens and I can select a certain file. The problem I have is that each time I am trying to open an open file dialog a second time my whole program freezes. I have no idea why this is happening. I have debugged my program and I've seen that each time the program freezes at the dialog.exec() method. This issue started after I have upgraded my qt creator to version 5.8. I have also tried deleting the dialog instance each time I press a button and creating a new one, the result was the same. I include the header #include < QFileDialog >. Bellow you have my code posted.
QFileDialog *dialog;
dialog = new QFileDialog(this);
dialog->setFileMode(QFileDialog::AnyFile);
dialog->setNameFilter(tr("Images (*.png *.xpm *.jpg *.bmp)"));
QStringList l;
QString file;
if (dialog->exec())
{
l = dialog->selectedFiles();
file = l.at(0);
//do things with the file
QMessageBox::information(this,"Image Loader","Image loaded successful");
}
If anyone knows how to solve this I would be grateful.

QFileDialog causes my application to become less responsive

Firstly, for context, I am connecting a signal from triggered from QAction to a slot called fileOpen in this, and other similar connections are done in a method in my main window class like the following:
void MainWindow::createActions()
{
m_fileNew = new QAction("&New", this);
m_fileOpen = new QAction("&Open", this);
m_fileExit = new QAction("E&xit", this);
connect(m_fileNew, SIGNAL(triggered(bool)), this, SLOT(fileNew()));
connect(m_fileOpen, SIGNAL(triggered(bool)), this, SLOT(fileOpen()));
connect(m_fileExit, SIGNAL(triggered(bool)), this, SLOT(fileExit()));
}
To show the file dialog, the static method QFileDialog::getOpenFileName is used in MainWindow::fileOpen:
void MainWindow::fileOpen()
{
QString filename = QFileDialog::getOpenFileName(this, tr("Open Audio File"),
"", tr("WAVE Files (*.wav);;All Files (*.*)"));
if (filename != QString::null) {
m_fileName = filename;
}
}
The signal-slot connection between m_fileOpen and fileOpen works and displays the file dialog, but after closing the dialog the window takes longer to redraw while resizing.
Why is that happening, and how can I fix it?
All I had to do was build my Qt application in release mode, which means removing the "CONFIG+=debug" argument from the qmake call.
In release mode the performance degradation is gone, which is great, although I don't understand what differences between the debug and release versions of the Qt libraries allow this to occur.

Close QFileDialog only when click "open"

Whenever I select a file in my QFileDialog the accepted signal is fired and the window closes. I want to keep the window open so I can select multiple files and then capture the signal fired when "open" is clicked.
QFileDialog* myDialog = new QFileDialog(this);
myDialog->setFileMode(QFileDialog::ExistingFiles);
myDialog->setVisible(true);
What signals should I be connecting here to achieve this effect?
The QFileDialog::ExistingFiles should guarantee that multiple files can be selected. Given that, you can connect to the signal:
void QFileDialog::filesSelected(const QStringList & selected)
Directly from the documentation:
When the selection changes for local operations and the dialog is accepted, this signal is emitted with the (possibly empty) list of selected files.
However, if you are only interested in collecting such files, you can totally avoid signal-slot and write (taken again from the documentation):
QStringList fileNames;
if (dialog.exec())
fileNames = dialog.selectedFiles();
Note that in this case dialog object has been created on the stack (which is the common approach for such objects).
Your code looks fine to me. I believe you are double clicking on the file inside the dialog instead of holding on the Ctrl and single clicking on all the files you need.
You can optionally use an event filter and ignore the double click event.
Once you click on Open, you can get a list of all the file paths in the QStringList given by QFileDialog::selectedFiles(). Also it's better to use a stack variable here and use exec method to launch it as pointed out by BaCaRoZzo.
QFileDialog myDialog(this);
myDialog.setFileMode(QFileDialog::ExistingFiles);
if(myDialog.exec())
{
qDebug() << myDialog.selectedFiles();
}
Whenever I select a file in my QFileDialog the accepted signal is fired and the window closes. I want to keep the window open so I can select multiple files
All other answers is just solution for selection many files one time and CLOSE window after Open button pressing. Get my solution, it is not very simple because it required lot of work:
I used lamda expressions and new signals and slots syntax in my answer, but you can use old syntax or add
CONFIG += c++11
to the .pro file and use lambdas.
Subclass QFileDialog:
Header:
#ifndef CUSTOMFILEDIALOG_H
#define CUSTOMFILEDIALOG_H
#include <QFileDialog>
#include <QDebug>
class CustomFileDialog : public QFileDialog
{
Q_OBJECT
public:
explicit CustomFileDialog(QWidget *parent = 0);
void setDefaultGeo(QRect);
signals:
void newPathAvailable(QStringList list);
public slots:
private:
bool openClicked;
QRect geo;
};
#endif // CUSTOMFILEDIALOG_H
When you click open, you hide your dialog, not close! Cpp:
#include "customfiledialog.h"
CustomFileDialog::CustomFileDialog(QWidget *parent) :
QFileDialog(parent)
{
openClicked = false;
connect(this,&QFileDialog::accepted,[=]() {
openClicked = true;
qDebug() << openClicked;
this->setGeometry(geo);
this->show();
emit newPathAvailable(this->selectedFiles());
});
}
void CustomFileDialog::setDefaultGeo(QRect rect)
{
geo = rect;
}
Usage:
CustomFileDialog *dialog = new CustomFileDialog;
QStringList fileNames;
dialog->setFileMode(QFileDialog::ExistingFiles);
dialog->show();
dialog->setDefaultGeo(dialog->geometry());
connect(dialog,&CustomFileDialog::newPathAvailable,[=](QStringList path) {
qDebug() << path;
});
Why do you need setDefaultGeo? Without this method, your window will move after Open pressing.
What we get?
I open filedialog and select two files:
I clicked Open, but window didn't close! You can choose new files again and again!
One more file and so on:
Window will closed only when user press Close button, but you will have all path which user choose.
As you said:
I want to keep the window open so I can select multiple files
You get this.
I don't think anyone has understood the question (or it could be just me looking for my own solution)...
I had the same issue. As soon as I clicked a file the dialog would close. I couldn't ever select a file and then click "Open" because the dialog instantly closed as soon as I single clicked a file.
related: qtcentre.org/threads/48782-QFileDialog-single-click-only
It turns out it was my linux os settings (under mouse). File opening was set to single-click. I still feel like something external might have toggled this but that is just speculation. It appears Qt was going the right thing. Check another application, like kate on KDE and see if it has the same behavior. That is what clued me in to the source of my issue.