The quit slot of QApplication is provided by Qt, but if we want to open an image when clicking on the open action, which slot should we use? In this scenario, there's no slot built-in for this kind of customized task. We should write a slot on our own.
To write a slot, first we should declare a function in the body of the class, MainWindow, and place it in a slots section. As this function is not used by other classes, we put it in a private slots section, as follows:
private slots: void openImage();
Then, we give this slot (also a member function) a simple definition for testing:
void MainWindow::openImage() { qDebug() << "slot openImage is called."; }
Now, we connect the triggered signal of the open action to the openImage slot of the main window in the body of the createActionsmethod:
Now, let's compile and run it again. Click the Open item from the File menu, or the Open button on the toolbar, and the slot openImage is called.message will be printed in the Terminal.
We now have a testing slot that works well with the open action. Let's change its body, as shown in the following code, to implement the function of opening an image from disk:
Let's go through this code block line by line. In the first line, we create an instance of QFileDialog, whose name is dialog. Then, we set many properties of the dialog. This dialog is used to select an image file locally from the disk, so we set its title as Open Image, and set its file mode to QFileDialog::ExistingFile to make sure that it can only select one existing file, rather than many files or a file that doesn't exist. The name filter Images (*.png *.bmp *.jpg) ensures that only files with the extension mentioned (that is, .png, .bmp, and .jpg) can be selected. After these settings, we call the exec method of dialog to open it. This appears as follows:
If the user selects a file and clicks the Open button, a non-zero value will be returned by dialog.exec. Then, we call dialog.selectedFiles to get the path of the files that are selected as an instance of QStringList. Here, only one selection is allowed; hence, there's only one element in the resulting list: the path of the image that we want to open. So, we call the showImagemethod of our MainWindow class with the only element to display the image. If the user clicks the Cancel button, a zero value will be returned by the exec method, and we can just ignore that branch because that means the user has given up on opening an image.
The showImagemethod is another private member function we just added to the MainWindowclass. It is implemented as follows:
In the process of displaying the image, we add the image to imageScene and then update the scene. Afterward, the scene is visualized by imageView. Given the possibility that there is already an image opened by our application when we open and display another one, we should remove the old image, and reset any transformation (for example, scaling or rotating) of the view before showing the new one. This work is done in the first two lines. After this, we construct a new instance of QPixmap with the file path we selected, and then we add it to the scene and update the scene. Next, we call setSceneRect on imageView to tell it the new extent of the scene—it is the same size as the image.
At this point, we have shown the target image in its original size in the center of the main area. The last thing to do is display the information pertaining to the image on the status bar. We construct a string containing its path, dimensions, and size in bytes, and then set it as the text of mainStatusLabel, which had been added to the status bar.
Let's see how this image appears when it's opened:
Not bad! The application now looks like a genuine image viewer, so let's go on to implement all of its intended features.