For this exercise we will use QtCreator to design a simple image viewer. Make sure you have a qtImage
directory in your w01-intro
folder.
Complete the QtCreator Initial Setup if you have not already done so.
Run qtcreator
then File->Open File or Project
select the file ~/cs40/examples/CMakeLists.txt
Click on the computer icon in the lower left and set the running application to qtimgtest
. Click the green arrow to build and run this application. A simple window should pop up.
click on mainwindow.ui
in w01-intro/qtimage
directory in QtCreator. The UI editor will open. Here you can add widgets and adjust the layout.
In the upper right corner, select the MainWindow widget. You can edit this widget's properties in the lower right menu. Find the windowTitle
property and change it to "My First Qt App". Run the question green arrow again and see that the title has changed.
Window
to something visible (I use green in this example)
MyImageBox
and have it inherit from QWidget
None
for version control. We'll do this manually later.
myimagebox.h
and myimagebox.cpp
to the qtimage/CMakeLists.txt
file with the other filenames in target_sources
MyImageBox
Graphical user interfaces such as Qt have event handling mechanisms to process events like keypresses, mouse clicks, and menu selection. In Qt, this mechanism uses slots and signals. Events emit signals which can then be sent to slots.
open()
slot to the green widget.
clicked()
signal to the open()
slot.
clicked()
signal to the close()
slot. You may need to click the "Show signals and slots inherited from QWidget" box to see the close()
slot for the MainWindow.
Add functionality to myimagebox.h
#include <QtWidgets> ... public slots: void open(); private: QLabel *imageLabel; QScrollArea *scrollArea; QGridLayout *layout;Implement in
myimagebox.cpp
MyImageBox::MyImageBox(QWidget *parent) : QWidget(parent) { imageLabel = new QLabel(); scrollArea = new QScrollArea(this); scrollArea->setWidget(imageLabel); layout = new QGridLayout(); layout->setContentsMargins(0,0,0,0); layout->addWidget(scrollArea); setLayout(layout); } void MyImageBox::open() { QString fileName = QFileDialog::getOpenFileName(this, "Open File", QDir::currentPath()); if (!fileName.isEmpty()) { QImage image(fileName); if (image.isNull()) { QMessageBox msgBox; msgBox.setText(QString("Cannot load %1.").arg(fileName)); msgBox.setIcon(QMessageBox::Information); msgBox.setWindowTitle("Image Viewer Load Error"); msgBox.exec(); return; } imageLabel->setPixmap(QPixmap::fromImage(image)); imageLabel->adjustSize(); } }
Compile, Debug, Run, Test, Ponies!
Check the status of your source in git and update/commit and push your changes
Don't worry about understanding every single line of code at this point. There are a few main takeaways to focus on at this point.
signal
and public slots:
code in Qt C++ programs, this is not standard C++, and some special Qt and compiler magic happens behind the scenes to make this work. The strange floating Q_OBJECT
is also part of this magic.
Below are some of the classes used in this demo. You don't need to memorize any of these as you can always refer back to the documentation, but some we will be using more often than others.