CS-321 Lab 4: Lines, Buttons, Color, and Polygons
Overview
In this lab, you will be addressing some of the common issues associated with
working in a graphical user interface; specifically adding code to work with
buttons. You will also introduce polygons as an additional shape
that your program can contain and display. Polygons are a particular case of a
class of shapes that exhibit variability in their size (i.e., number of vertices).
Bezier curves, which you'll learn about shortly, is a type of curve that uses a
variable number of control points in its definition.
Since there are other shapes besides polygons that
have a variable number of vertexes, it wouldn't be good to reinvent the
wheel (e.g., file reading and writing code) for each one. Therefore, you must derive your
Polygon class from another new abstract class you define called VariableShape
that encapsulates common elements and behavior of polygons, polylines, Bezier
curves, etc.
The VariableShape class must be generic enough to be used
later as a base class for other shapes that are similarly defined by a variable
number of vertexes or control points. This abstract class should implement the
behavior common to all concrete classes derived from it, such as Read, Write,
and AddNode. Any derived class, such as Polygon, will still need to implement
methods such as constructors, the destructor, and operator=, but it can use the
equivalent abstract base class methods to do the actual work. You also need to
override Draw and Clone in the derived concrete class.
Here is the UML class diagram illustrating the
relationship between the classes:
Activities
- Continue to ignore the virtual functions from Shell
concerning Zoom, Unzoom, and Reset.
- Review the Qt documentation on both
QPushButtons and
Signals and Slots.
- Add three buttons to the
mainLayout
widget of the Shell in your derived shell class constructor—one to put the
Shell in Point drawing mode, one to put the Shell in Line drawing mode, and
a third to put it in Polygon drawing mode.
- Using the connect macro/function have the
corresponding clicked() signal of each button call a
new (possibly virtual) slot (e.g., member function) in your derived
shell that changes a derived shell member variable so that Draw
knows how the mouse is to be used. You may want to get fancy and add a
mechanism to indicate which drawing mode your program is in.
- Don't forget to include the Q_OBJECT macro in your
shell header and to indicate which of the member functions are to be the
new slots.
- Also note that all widgets (e.g., the buttons) should be dynamic
(i.e., created using new).
- You will also need to make sure that all of your HEADERS
are in your project file and you will have to re-qmake it so that
Q_OBJECT is handled correctly.
- Add a style command to the command parser that allows
the user to select one of the 5 Qt PenStyles.
- Once a new PenStyle is selected, all subsequent new shapes should
appear in that style until a new and valid style command is entered.
- During an exposure redraw each shape should appear in the style in
which it was first drawn, so you will need to save the style information
with the shape itself.
- Even though the style doesn't have an effect on drawing points,
include it for the point class to support greater consistency and reuse
among the classes derived from shape.
- Since style is an attribute that will apply to all shapes, the job of reading and writing this common attribute can be
delegated to the shape base class.
- Add a color command to the command line parser that
invokes the QColorDialog
- The rules for remembering and saving colors are analogous to those
for styles. To understand colors in Qt, however, you should research the
QColor class. As you
research QColor, consider whether it is easier to store each color as 3
components, or if there is some way to combine the components into a
single value.
- add a color attribute the shape class to hold the color value for
each shape.
- After adding the Polygon button to your shell, you
must develop a
mechanism for specifying polygons using the mouse. It is recommended that you
keep the points specified by the user in a container and only create a polygon
object and Add() it to your image when the user indicates that the polygon is finished
by double-clicking.
- You MUST have a Polygon class. It is NOT
acceptable to save a polygon as a bunch of lines. Note that QPainter has a
drawPolygon()
function.
- Make certain that your code accounts for an unexpected
order of events. For example what happens when a user switches drawing mode
while drawing a polygon, a Paint event occurs during a polygon specification,
or the user executes a text command? There are a number of reasonable ways to
handle these situations; make sure that your program does something well
defined and does not crash.
- You must fill the polygon. You may want to get
fancy with this and draw the polygon edges with a different color than
the fill, but you don't have to. You may also want to give the user the
ability to choose odd-even or non-zero-winding fill; again this is
optional (see below).
- Don't forget to update your help information.
- Make certain that your polygons (or more
generally, VariableShape's) can be read from and
written to files.
- It is NOT REQUIRED to implement adding a polygon
from the command line.
- For drawing lines, use the QPainter::drawLIne() method.
"A" level grade: When a line has a slope 0<m<1,
implement Bresenham's algorithm (this is actually pretty easy) to draw the
line as a series of points using QPainter::drawPoint(). For other slopes,
use drawLine(). This must be done by the 2nd week of lab.
- Optional (5 pts extra): Add the option (via the command line
parser) to choose odd-even or non-zero-winding for the polygon fill.
- MANDATORY: Commenting source code is an important aspect of software
development, whether you're a CE or SE. When you program conditional logic,
every if, else, switch, and while should be commented.
- MANDATORY: Symbolic constants should be used whenever possible in place
of literals. The QT library provides symbolic constants to represent many
different types of values (color, for example). QT also defines symbolic
constants for events types, such as PAINT. Use symbolic constants rather
than literal values in your Draw method (for example) to make it clear
(along with comments) what each section of code is used for.
Hints
- Add one function at a time, beginning with UI layout
and button setup (followed by
button signals/slots, multiple color support) and test each function before moving on to the next one.
- For UI modification, look up QHBoxLayout,
QHButtonGroup, QPushButton, and QLabel.
Demonstrations (during both week 6 and 7 labs)
You will need to demonstrate your modified user interface to
me during the week 6 lab meeting. At a minimum, this should include the 3 new
buttons you must add (Point, Line and Polygon). When these buttons are pressed,
they should minimally put your program into Point or Line drawing mode. You do
not have to implement Polygon support during the first week. This milestone must be reached by the week 6 lab;
otherwise, late points will begin to incur.
You will need to demonstrate your completed project to me during the week
7 lab meeting.
Lab assignment (due the day of Lab 5)
This is a 2 week lab.
Fix all errors from your previous lab!
Submit your assignment following these instructions:
-
In addition to your Word report file,
I only want:
Lab3DerivedShell.cpp
Line.cpp
VariableShape.cpp
VariableShape.h
Polygon.cpp
Polygon.h
- Use
webCT to
submit your
assignment ("Lab 4").
Do not zip the files.
- Record the time (in minutes) you spent on
this lab in the FAST system for weeks 5 and
6.
Be sure to keep copies of all your files, in case something gets lost.Your lab grade will be determined by the following
factors:
Program quality
- Meeting requirements/correct program operation/output.
- Technical quality (comments, formatting, naming)
Report quality
- Required content
- Spelling and grammar (your word-processing program has
a built-in spell checker
- use it)
- Timeliness of submission as stated in the
course policies.
If you have any questions, consult me.