Programing in C++
Lab 5: Using an Additional Library: The Qt Framework
General conditions
Important! Read the conditions for completing the assignments on the subject's website! Tasks are submitted via the form on the subject's website. Solutions will not be accepted via email. If you have any questions, please contact the lab supervisor.
You have 14 days to solve the task.
Deadline: 17.04.2022 23:59:59
Note: Please use the Qt framework 5.0 or later.
General requirements
Write a drawing program that can be used to draw points and straight lines that connect them. Revisit the DynamicLine
class of the fourth lab and its application ideas.
NB! The task requires that you reuse the DynamicLine
class.
The basic program of the internship includes a simple Qt project with project files with a .pro extension. Inside Qt Creator work environment the program can be compiled and started in an easy way.
This lab is exceptional, as the Makefile is not required when submitting a solution. Qt Creator is used to test solutions. NB! The exception does not apply to other labs.
It is your job to complete the basic program according to the requirements of the task. As usual, there are links to the materials on the lab website.
Task 1 – Fix the main window size (1 point)
The base program Joonistamine
(drawing) window is currently resizable, which can make the
later tasks more difficult. Fix the window size to be 800x600 pixels and disable resizing of the
main window.
Task 2 – General appearance of the program (1 point)
The background of the 800x600 drawing area of the program window should be your favorite color, such as bluish green. The main menu of the program should have a menu "Tools" for selecting a tool, which contains the following elements:
Add point Move point Delete point Add line Delete line
Add a three-part status bar to the bottom of the main program window. The first part should show the name of the currently active tool. The second and third part should show how many points and lines are in the drawing area (“Points: <count>, “Lines: <count>”). Hint: You can use the QLabel class to add text areas to the status bar.
The required commands can be found from Qt documentation, either Qt Creator’s documentation or from the Internet:
- Signals and slots: http://qt-project.org/doc/qt-5.0/qtcore/signalsandslots.html
- QMainWindow: http://qt-project.org/doc/qt-5.0/qtwidgets/qmainwindow.html
- QWidget: http://qt-project.org/doc/qt-5.0/qtwidgets/qwidget.html
- QMenuBar: http://qt-project.org/doc/qt-5.0/qtwidgets/qmenubar.html
- QStatusBar: http://qt-project.org/doc/qt-5.0/qtwidgets/qstatusbar.html
- QMenu: http://qt-project.org/doc/qt-5.0/qtwidgets/qmenu.html
- QAction: http://qt-project.org/doc/qt-5.0/qtwidgets/qaction.html
- QLabel: http://qt-project.org/doc/qt-5.0/qtwidgets/qlabel.html
Task 3 – Adding points (2 punkti)
If the user has selected "Add point" from the menu, the program is in point adding mode. The text in the first part of the status bar indicates this. When a program is in point adding mode, pressing the left mouse button at a point in the drawing area creates a point at that location. The point is marked with a black circle about 20 pixels in diameter. The point is not added if there is already a point within a radius of 10 pixels. Use previously created methods to search for nearby points. If one point is added, the program remains in point additing mode.
To do this, the mouse click processing method must be implemented in the drawing area:
void QWidget::mousePressEvent(QMouseEvent *event);
Also, this method must be implemented:
void QWidget::paintEvent(QPaintEvent *event);
Tip: You need to create data structures to save the state (points, lines), update it with a mouse click, and draw it on the screen based on the data in paintEvent.
Mouse buttons are listed in Qt :: MouseButton (found in QMouseEvent). The QPainter class is also helpful: http://qt-project.org/doc/qt-5.0/qtgui/qpainter.html. There is also documentation about rendering in the QRect class documentation:: http://qt-project.org/doc/qt-5.0/qtcore/qrect.html.
Task 4 – Moving points (2 points)
If "Move point" is selected from the menu, the program enters point moving mode. The corresponding status bar text should be „Moving points“. When the user clicks the left mouse button on a point on the drawing area or up to 10 pixels away from it, the point becomes moveable and the user can move the point by moving the mouse. If there is a line connected to the point, it must move with the point. When the user releases the mouse button, the point remains in place at the new location. The point cannot be moved out of the drawing area. After moving one point, the user can select the next point. If there are no points in the drawing area, you cannot enter this mode.
The solution earns points if the points can be moved and the lines move with the point.
To do this, additional methods must be implemented in the drawing area:
void QWidget::mouseMoveEvent(QMouseEvent *event); void QWidget::mouseReleaseEvent(QMouseEvent *event);
Task 5 – Deleting points (2 points)
The choice of deleting points from the menu enables user to delete drawn points. In the status bar “Deleting points” should be displayed. Left-clicking on a point (or within a 10-pixel radius) deletes the point and any associated lines. Once one point is deleted, the user can immediately delete the next point. If there are no points in the drawing area, the user cannot enter this mode.
Task 6 – Adding lines (2 punkti)
The option "add line" from the menu takes the program to the add a line mode. This is only possible if two or more points exist. The status bar should be set to „Adding lines“. The user can now select the first point by pressing the left mouse button on some points (the 10 pixel radius requirement still applies). By pressing the left mouse button near another point (or 10 pixels), the user can select another point. When the user has successfully selected two different points, a line is created between them. The line is drawn as a 1-pixel thick black line. The program is still in line addition mode and the user can select the first point.
Tip: If the first point is selected, paint it in a different color. It is not mandatory for evaluation, but it makes the program more convenient and more fun to test.
Bonus task 7 – Deleting a Straight Line (1 additional point)
When the user selects "Delete line" from the menu, he enters the mode „Deleting lines“. In this mode, pressing the left mouse button deletes the line where the mouse cursor is.
To delete a line, the user must left-click on the line or a pixel away from it. For example, use line equations to find straight lines that pass through a pixel. You can find material here: http://www.cut-the-knot.org/Curriculum/Calculus/DistanceToLine.shtml.
If several lines pass through one pixel, delete the first one you find. The user can delete multiple straight lines in a row.
Tips for a solution
- If you are not using Qt Creator when you add new files, you must also add their names to the corresponding Qt project file (file extension .pro).
- Use a data structure to hold the points and lines attached to the drawing. Note that because
DynamicLine
keeps references to points, you must ensure that the addresses of the points given toDynamicLine
do not change during operation. - Be very careful when using a
std::vectordata
structure to store points. Adding or removing points in the middle of a vector can causeDynamicLine
point references to no longer apply. - Write function that returns the closest line to the given coordinates. You can also do this if no points within a radius of 10 pixels are returned. Use this function wherever you need to select a point. A similar function can be written for lines.
- The
tr()
function can be used to make applications easier to translate. For example:m_label->setText (tr ("Siia tuleb tekst"));
(more info: http://qt-project.org/doc/qt-5.0/qtcore/qtranslator.html). - If the code doesn't work exactly as it should, it's a good idea to use a debugger, which usually helps you track down the problem faster than just printing the text on the screen.