- 10.1 Why graphics?
- 10.2 A display model
- 10.3 A first example
- 10.4 Using a GUI library
- 10.5 Coordinates
- 10.6 Shapes
- 10.7 Using Shape primitives
- 10.8 Getting the first example to run
10.8 Getting the first example to run
We have seen how to make a window and how to draw various shapes in it. In the following chapters, we’ll see how those Shape classes are defined and show more ways of using them.
Getting this program to run requires more than the programs we have presented so far. In addition to our code in main(), we need to get the interface library code compiled and linked to our code, and finally, nothing will run unless the GUI system we use is installed and correctly linked to ours. Previous editions of the PPP code used the FLTK library; the current version uses the more modern Qt library. Both work over a wide range of systems.
One way of looking at the program is that it has four distinct parts:
Our program code (main(), etc.)
Our interface library (Window, Shape, Polygon, etc.)
The Qt library
The C++ standard library
Indirectly, we also use the operating system.
10.8.1 Source files
Our graphics and GUI interface library consists of just five header files:
Headers meant for users (aka “user-facing headers”):
Point.h
Window.h
Simple_window.h
Graph.h
GUI.h
To implement the facilities offered by those headers, a few more files are used. Implementation headers:
Qt headers
GUI_private.h
Image_private.h
Colormap.h
Code files:
Window.cpp
Graph.cpp
GUI.cpp
GUI_private.cpp
Image_private.cpp
Colormap.cpp
Qt code
We can represent the user-facing headers like this:
An arrow represents a #include. Until Chapter 14 you can ignore the GUI header.
A code file implementing a user-facing header #includes that header plus any headers needed for its code. For example, we can represent Window.cpp like this
In this way, we use files to separate what a user sees (the user-facing headers, such as Window.h) and what the implementation of such headers uses (e.g., Qt headers and GUI_private.h. In modules, that distinction is controlled by export specifiers (§7.7.1).
This “mess of files” is tiny compared to industrial systems, where many thousands of files are common, not uncommonly tens of thousands of files. That’s one reason we prefer modules; they help organize code. Fortunately, we don’t have to think about more than a few files at a time to get work done. This is what we have done here: the many files of the operating system, the C++ standard library, and Qt are invisible to us as users of our graphics interface library.
10.8.2 Putting it all together
Different systems (such as Windows, Mac, and Linux) have different ways of installing a library (such as Qt) and compiling and linking a program (such as ours). Worse, such set-up procedures change over time. Therefore, we place the instructions on the Web: www.stroustrup.com/program-ming.html and try to keep those descriptions up to date. When setting up your first project, be careful and be prepared for possible frustration. Setting up a relatively complex system like this can be very simple, but there are usually “things” that are not obvious to a novice. If you are part of a course, your teacher or teaching assistant can help, and might even have found an easier way to get you started. In any case, installing a new system or library is exactly where a more experienced person can be of significant help.
Drill
The drill is the graphical equivalent to the “Hello, World!” program. Its purpose is to get you acquainted with the simplest graphical output tools.
[1] Get an empty Simple_window with the size 600 by 400 and a label My window compiled, linked, and run. Note that you have to link the Qt library, #include Graph.h and Simple_window.h in your code, and compile and link Graph.cpp and Window.cpp into your program.
[2] Now add the examples from §10.7 one by one, testing between each added subsection example.
[3] Go through and make one minor change (e.g., in color, in location, or in number of points) to each of the subsection examples.
Review
[1] Why do we use graphics?
[2] When do we try not to use graphics?
[3] Why is graphics interesting for a programmer?
[4] What is a window?
[5] In which namespace do we keep our graphics interface classes (our graphics library)?
[6] What header files do you need to do basic graphics using our graphics library?
[7] What is the simplest window to use?
[8] What is the minimal window?
[9] What’s a window label?
[10] How do you label a window?
[11] How do screen coordinates work? Window coordinates? Mathematical coordinates?
[12] What are examples of simple “shapes” that we can display?
[13] What command attaches a shape to a window?
[14] Which basic shape would you use to draw a hexagon?
[15] How do you write text somewhere in a window?
[16] How would you put a photo of your best friend in a window (using a program you wrote yourself)?
[17] You made a Window object, but nothing appears on your screen. What are some possible reasons for that?
[18] What library do we use to implement our graphics/GUI interface library? Why don’t we use the operating system directly?
Terms
color |
graphic |
JPEG |
coordinates |
GUI |
line style |
display |
PPP_graphics |
library |
software layer |
fill |
Shape |
color |
HTML |
window |
Qt |
image |
XML |
Simple_window |
|
Exercises
We recommend that you use Simple_window for these exercises.
[1] Draw a rectangle as a Rectangle and as a Polygon. Make the lines of the Polygon red and the lines of the Rectangle blue.
[2] Draw a 100-by-30 Rectangle and place the text “Howdy!” inside it.
[3] Draw your initials 150 pixels high. Use a thick line. Draw each initial in a different color.
[4] Draw a 3-by-3 tic-tac-toe board of alternating white and red squares.
[5] Draw a red 1/4-inch frame around a rectangle that is three-quarters the height of your screen and two-thirds the width.
[6] What happens when you draw a Shape that doesn’t fit inside its window? What happens when you draw a Window that doesn’t fit on your screen? Write two programs that illustrate these two phenomena.
[7] Draw a two-dimensional house seen from the front, the way a child would: with a door, two windows, and a roof with a chimney. Feel free to add details; maybe have “smoke” come out of the chimney.
[8] Draw the Olympic five rings. If you can’t remember the colors, look them up.
[9] Display an image on the screen, e.g., a photo of a friend. Label the image both with a title on the window and with a caption in the window.
[10] Draw the source file diagram from §10.8.1.
[11] Draw a series of regular polygons, one inside the other. The innermost should be an equilateral triangle, enclosed by a square, enclosed by a pentagon, etc. For the mathematically adept only: let all the points of each N-polygon touch sides of the (N+1)-polygon. Hint: The trigonometric functions are found in <cmath> and module std (PPP2.§24.8).
[12] A superellipse is a two-dimensional shape defined by the equation ; where m > 0 and n > 0.
Look up superellipse on the Web to get a better idea of what such shapes look like. Write a program that draws “starlike” patterns by connecting points on a superellipse.
Take a, b, m, n, and N as arguments. Select N points on the superellipse defined by a, b, m, and n. Make the points equally spaced for some definition of “equal.” Connect each of those N points to one or more other points (if you like you can make the number of points to which to connect a point another argument or just use N–1, i.e., all the other points).
[13] Find a way to add color to the lines from the previous exercise. Make some lines one color and other lines another color or other colors.
Postscript
AA
The ideal for program design is to have our concepts directly represented as entities in our program. So, we often represent ideas by classes, real-world entities by objects of classes, and actions and computations by functions. Graphics is a domain where this idea has an obvious application. We have concepts, such as circles and polygons, and we represent them in our program as class Circle and class Polygon. Where graphics is unusual is that when writing a graphics program, we also have the opportunity to see objects of those classes on the screen; that is, the state of our program is directly represented for us to observe – in most applications we are not that lucky. This direct correspondence between ideas, code, and output is what makes graphics programming so attractive. Please do remember, though, that graphics/GUI is just an illustration of the general idea of using classes to directly represent concepts in code. That idea is far more general and useful: just about anything we can think of can be represented in code as a class, an object of a class, or a set of classes.