PDA

View Full Version : How can I add a GUI file selection component to my console application?



icoachmarshmallows
21st April 2020, 19:32
Hi all,

I'm still learning Qt, but I've run into a bit of a problem. Currently, my console application reads a list of file names from the user via stdin. These filenames are then stored in a vector that is passed back to the invoking class. It works perfectly fine in its console form right now, but what I'd like to do is read in the filenames from the user via a GUI window that pops up when the old file selection prompt would come up on stdout so that the user can browse local files and select the file(s) that they want processed rather than typing them in. I'm confused right now as to how I'd go about doing this using Qt widgets. I'm developing on Ubuntu, but I have test environments for both Ubuntu and Windows 10. Ubuntu is my target platform, though, and I'm using Qt 5.

How can I invoke a GUI file-selection window and store the captured results into an std::vector? Again, I'm not actually opening the files yet as that is done a little later on in the flow of the application. I really only need for the user to be able to select files and then have the names of those files stored into an std::vector.

Any tips or pointers are more than appreciated! Thanks everyone.

d_stranz
21st April 2020, 20:59
Qt GUI programs are in general event-driven as opposed to the procedural model of most console apps, so in most cases you will probably have to develop a full-blown GUI app in order to use GUI components.

However, the QFileDialog class, the GUI component for interactive user selection of filenames, does have a static member function that might work in a console program: QFileDialog::getOpenFileNames(). It returns a QStringList of the selected files. This cannot directly be converted into an STL vector, but it does have a static member function in the base class (QList<T>) that will convert into an STL list<T>. Otherwise you can iterate over the QStringList to pull out the QString entries and push them onto a vector one by one.

If your vector is of std:: string or wstring, QString has converters for that also.

You will probably have to have a QApplication instance in your console app in order for this to work, since there needs to be an event loop running. However, I have never tested this idea, so it may not work anyway.

icoachmarshmallows
22nd April 2020, 18:10
Hi there,

Thank you for your response. I appreciate the insights, and I was able to get something together with your advice as a guide.

I've run into one little problem, though, and I think it may have to do with the event loop you referenced. If anyone has any time, I'd greatly appreciate a response.

I have integrated the QFileDialog::getOpenFileNames() into my console application, and it seems to be working well with one caveat. I'll try to explain the situation as best I can.

The instance of QApplication is declared/initialized in my main() application. Then, a class is instantiated that gathers input values (including the files) from the user. Once the user has entered their values, their inputs are shown back to the user so that they can verify their inputs were correct. The QFileDialog::getOpenFileNames() works perfectly the first run through, but if the user made an error during the input-gathering step, they're allowed to reenter all of their inputs. It's basically "If user is unhappy with inputs, restart input-gathering process from the start. Rinse and repeat until they're happy." So, if the user is unhappy with their input, everything runs fine until they're prompted to select file(s) again. The file-browsing/selection box pops up like it did the first time, but the box doesn't go away when the user clicks "Open". Instead, the window hangs there. However, the action of storing the filenames into my QStringList object still works as verified on the still-running console application. If you can imagine, the file-selection step is the last step in gathering the user's input before the input-verification screen pops up. So, the console application proceeds to the screen that displays the user's input back to them, and the QFileDialog::getOpenFileNames() window stays there until the user says "Yes these values are good, let's continue" or "No, these values are bad, let me try again" at which point the window goes away.

That was a bit long-winded, but I hope that it conveyed the situation I find myself in. I wonder if the event loop stops running at that point for some reason and the window just stays there as a zombie or something. I admit that my insight into Qt is lackluster, so I may be glossing over something important. I apologize if that's the case.

Again, thanks for the help d_stranz! I do appreciate it.

Lesiok
23rd April 2020, 06:54
For proper operation, the GUI needs a working application event loop.