• Aucun résultat trouvé

File Selection Dialogs

Dans le document Qt 4 THE BOOK of THE BOOK of (Page 177-181)

Laying Out Widgets

6.5 Ready-made Dialogs in Qt

6.5.3 File Selection Dialogs

Applications frequently use dialogs to prompt the user to select files or directories.

For this reason nearly all platforms provide implementations of such selection di-alogs. Each one has its own special features, to which the end users of applications quickly become accustomed.

As a platform-independent toolkit, Qt is in somewhat of a quandary here: On the one hand the user should be able to use his or her own system dialog, but on the other, these dialogs cannot be extended with the widgets you as a programmer have written.

The QFileDialog class, which implements the file and directory selector, is therefore split into two parts: If you instantiate the class via the constructor, then Qt displays a separate dialog. If you use the predefined static methods, on the other hand, which cover most needs of application developers, then Qt tries to use the file dialog for the appropriate operating system.6

If you explicitly want to usenonative system dialogs, you notify static methods of this via the QFileDialog::DontUseNativeDialog flag. In this case Qt uses its own dialog at the corresponding position. This and other flags are documented in Table 6.2.

Table 6.2:

Options for QFileDialog

Value Effect

QFileDialog::ShowDirsOnly Show only directories.

QFileDialog::DontResolveSymlinks Donotresolve symbolic links, but in-terpret them as regular files or direc-tories.

QFileDialog::DontConfirmOverwrite Do not confirm whether an existing file should be overwritten.

QFileDialog::DontUseSheet Do not display the Open file dialog in Mac OS X as a sheet. Only works if DontUseNativeDialog isnotset.

QFileDialog::DontUseNativeDialog Always use Qt’s own dialog.

File Selection Dialogs

In an initial example, illustrated in Figure 6.12, we want to allow the user to select an image. To do this we use the static method getOpenFileName():

6 An exception is provided by the X11 platform. Currently, the Portland project (http://portland.freedesktop.org/) is working on a solution in which applications can use the file dialogs of the currently running desktop environment (GNOME or KDE).

QString file = QFileDialog::getOpenFileName(

this,

tr("Pick a File"),

"/home",

tr("Images (*.png *.xpm *.jpg)"));

If successful, the method call returns a filename; otherwise, it returns a null QString (which can be checked with file.isNull()). As the first argument, the method expects a pointer to the dialog’s parent widget. If a null pointer is given as the first argu-ment, then the dialog will not be modal. The next two arguments are the dialog heading and the start directory.

The QDir class provides static methods for retrieving the paths to the most im-portant directories, which can be used as the third argument instead of a fixed string:7

QDir::currentPath()

This returns the current directory of the application.

QDir::homePath()

Under Windows, this returns the contents of the HOME environment vari-able. If this does not exist, it tries to evaluate the USERPROFILE environ-ment variable. If this also fails, Qt forms the directory from HOMEDRIVE and HOMEPATH. If these variables are also not set, the method calls rootPath().

In Unix systems, including OS X, the method uses the HOME environment variable. If this is not set, rootPath() is used.

QDir::rootPath()

In Windows, this returns drive C:\; in Unix, the root directory /.

QDir::tempPath()

This is /tmp in Unix, while in Windows it is based on the environment vari-ables TEMP and TMP.

Finally, as the fourth argument, getOpenFileName() expects a file filter. It allows only files with specific endings to appear in the dialog. Here you must adhere to the following syntax:

"filetypedesignator(*.ex1 *.ex2 ... *.exn)"

The file type designator can be freely chosen. It explains to the user what sort of file is involved. The file extensions listed in the parentheses act as the actual filter for the filenames contained in the directory. The following filter, for example, finds all files that end in .png, .xpm, or .jpg:

7 For an example see page 178.

"Images (*.png *.xpm *.jpg)"

Every filter should be made localizable, that is, enclosed by tr(). In this way, readers of other languages can still enjoy a file type description in their own language.

If the user himself should decide which filters are to be used, alternatives can be appended to the first filter, separated from it by two semicolons. For example, if the filter is

"Images (*.png *.xpm *.jpg);;Text files (*.txt)"

then a corresponding drop-down dialog appears in the Open file dialog, as in Figure 6.12.

Figure 6.12:

The static methods of QFileDialogallow the use of standard dialogs with their own filters.

We can now choose from exactly those files that have either one of the three graphic file extensions or the extension .txt in this example. In general, the amount of filters is of course not limited.

Selecting Several Files Simultaneously

If a user needs to be able to select several files simultaneously, this possibility is covered by the getOpenFileNames() static method. In contrast to its little sister getOpenFileName(), it returns a QStringList, but the arguments are identical. Each entry in the returned list corresponds to a selected file.

This method of QFileDialog also makes use, in Windows and OS X, of the native dialogs of the corresponding operating system. The following example prints all the selected files, together with their paths, to the debug stream:

QStringList fileList = QFileDialog::getOpenFileNames(

this,

tr("Pick a File"),

"/home",

tr("Images (*.png *.xpm *.jpg)"));

foreach(QString file, fileList) qDebug() << file;

Selecting Existing Directories

Some programs require a base directory for their operations. When prompting the user for this path, the application must prevent the user from specifying a file target. A photo-manipulating program, for example, cannot store its gallery beneath a file.

To ensure that the user is shown only directories, you can call the file dialog class’s getExistingDirectory() method. This does not expect a filter and displays only di-rectories. Furthermore, it checks to see whether a specified directory really does exist—the user or another application could have deleted it in the meantime.

The following example queries the user for a directory, in which the program in-tends to store all its photos in future. As the base directory we will use the home directory of the current user:

QString directory = QFileDialog::getExistingDirectory(

this,

tr("Please pick the folder containing the photo gallery."), QDir::homePath());

Selecting a Filename

If a user wants to save a file, this file usually does not yet exist. getOpenFileName() tests whether the specified file exists, however, so it is of no use for saving files. We require a new static method that meets the requirements of storage semantics. In Qt this function is called getSaveFileName(), and it is analogous in its arguments and in its return value to getOpenFileName().

The following example requires the user to select the name of a file in which to save data. Here, if the user selects the name of an already existing file, the program does not question this, thanks to the DontConfirmOverwrite flag. This can be useful, for example, if the program wants to investigate the state of affairs outside the dialog.

QString file = QFileDialog::getSaveFileName(

this,

tr("Save File As..."), QDir::homePath(),

tr("Images (*.png *.xpm *.jpg)"), QFileDialog::DontConfirmOverwrite );

Dans le document Qt 4 THE BOOK of THE BOOK of (Page 177-181)