The call to drawPolyLineon line 32 uses the same input information as drawLineSegments, but it draws all the line segments by starting each new line seg-ment at the point where the previ
Trang 1You can think of a pixel as the shortest of all possible lines Line 22 calls setPen()
to establish a white pen for drawing the points, and line 31 calls setPen()to lish the red pen for drawing the dots making up the curve
estab-The loop on lines 23 through 30 draws the collection of white points shown inFigure 12-9 The points are drawn at 20-pixel intervals both vertically and horizon-tally Each point is drawn as four pixels — one above and one to each side of thecenter point
The loop on lines 32 through 37 draws a sine wave that increases in amplitude fromleft to right The variables xand yare declared as doubleto simplify the calcula-tions The window is fixed at 400 pixels wide, so the value of xvaries from 0 to 400,resulting in one painted pixel in each of the 400 “pixel columns.” Line 33 calculatesthe sine, treating the value of xas a number of radians (using a divisor other than 30here will change the number of cycles that appear in the window) Line 34 multipliesthe yvalue such that its magnitude becomes larger as xbecomes larger Line 35adds 100 to the yvalue so it will be vertically centered in the window The call to
drawPoint()on line 36 paints the pixel
Trang 2278 Part II ✦ Step by Step
Drawing Arrays of Pixels
In the previous example, all of the points were calculated each time the windowwas painted Sometimes it is more convenient to calculate the points only once, orload them from a file and store them in an array The following example displays thesame window as the previous example, shown in Figure 12-9, but it calculates thepixel locations only once and stores them in an array
Lines 13 and 14 declare pointers to a pair of QPointArrayobjects The one named
curveis used to contain the points defining the trace, and the one named gridwillcontain the locations of the white points in the background
Trang 3The QPointArrayobject to contain the grid points is created on line 20 There isone entry in the array for each of the points, so the total size of the array is theproduct of 4 (the number of pixels in each grid point), 20 (the number of grid points
that will appear along the x axis), and 10 (the number of grid points that will appear along the y axis) The loop on lines 22 through 29 inserts four pixel locations for
each of the grid points
The QPointArrayobject to contain the trace of the curve is created on line 30 Thecalculations, and the number of points, are the same as they were in the previousexample There are 400 points calculated, and all 400 are stored in the array by thecall to setPoint()on line 36
Trang 4280 Part II ✦ Step by Step
The paintEvent()method starting on line 39 has much less to do than in the previous example A QPainterobject is created, a white pen is used to draw thepoints defined in grid, and a red pen is used to draw the points in curve
Sometimes you need to recalculate the values under some circumstances, but notunder others For example, if you wish to recalculate the values only when the win-dow changes size, the top of your paintEvent()method — using the values in
QPaintDeviceMetrics— determines whether the window size has changed and,
if so, calls the method that does the calculation
Vector Line Drawing
Two methods can be used to implement vector drawing They don’t do anythingthat can’t be done with drawLine(), but they can be very convenient in the cre-ation of certain kinds of drawings The methods moveTo()and lineTo()are reallyleft over from the days when graphics were done using a pen plotter Both methodsmove the pen from one location to another, but only one of them holds the pendown, causing a line to be drawn The pen always has a position, so in order todraw a line, it is only necessary to specify the other end of the line Once the linehas been drawn, the pen assumes the new position
The following example reads the drawing instructions from a file and uses them todisplay the graphic shown in Figure 12-10 Each line of the input text file contains anopcode (mfor move and dfor draw) and the coordinate point for the action to takeplace The file used in this example starts like this:
The first line is an instruction to move to the point (60,110) The second commandwill draw a line from the pen’s position at (60,110) to a new location at (60,10)
Figure 12-10: A line drawing
defined in a file
Trang 6282 Part II ✦ Step by Step
Line Segments and Polygons
Some QPaintermethods allow you to store a set of points in a QPointArrayobjectand then use the points to draw polygons The following program demonstratessome of the different ways a collection of line segments can be drawn:
Trang 7The setPoints()method on line 41 inserts the points into the array The same set
of points is used for each drawing, as shown in Figure 12-11, except the horizontalposition is shifted to the right by the amount of the offset
Figure 12-11: Five ways to draw a polygon
The call to drawLineSegments()on line 26 draws the version of the polygonshown on the far left of Figure 12-11 The lines are not joined together because only line segments are drawn That is, the first line is drawn between point[0] andpoint[1], the second is drawn between point[2] and point[3], and so on For everyline drawn, there must be two members in the array of points Of course, you canforce the lines to join into a polygon by using the ending point of a line as the start-ing point of the next
The call to drawPolyLine()on line 32 uses the same input information as drawLineSegments(), but it draws all the line segments by starting each new line seg-ment at the point where the previous line segment left off That is, the first line isdrawn between point[0] and point[1], the second is drawn between point[1] andpoint[2], and so on In the array of point data, the last point does not coincide withthe first point, so the polygon is not closed
The call to drawPolygon()on line 32 draws the figure in the same way as drawLineSgemetns(), but it also draws a line from the end point back to the beginning,resulting in a closed shape
The call to drawPolygon()on line 36 draws the shape after a QBrushhas beenstored in the QPainterobject, and this results in the polygon being filled Just aswith any of the other shapes, the area is filled before it is outlined, causing the out-lining to appear on top of the fill The second argument to the method call sets thewinding rule to TRUE, which means that all areas of the polygon will be filled with-out regard to overlaps of itself
Trang 8284 Part II ✦ Step by Step
The call to drawPolygon()on line 39 is the same as the previous one, except thewinding rule is set to FALSE This setting means that the only regions of the poly-gons that are filled are those covered with an odd number of layers The rightmostdrawing in Figure 12-11 shows that the area where the shape overlaps itself is notfilled — that is, there are two layers of the shape at the overlap point If the shapewere to overlap the same point with a third layer, it would be filled again
Ellipses and Circles
The method drawEllipse()is used to render both circles and ellipses because
a circle is simply an ellipse with equal height and width The following program displays the window shown in Figure 12-12, containing two ellipses and a circle:
Trang 9Chapter 12 ✦ Drawing and Painting with QPainter
The drawEllipse()method requires that you define a bounding box to specify thefour sides of the ellipse The bounding box is defined by the xand ycoordinates ofits upper-left corner, and the width and height of the box For example, the ellipse
on the left in Figure 12-12 is drawn by the call to drawEllipse()on line 23, with itsupper-left corner 10 pixels from the left edge and 50 pixels from the top The width
of the ellipse is 110 pixels and its height is 40 pixels
A QBrushobject is added to QPainterby the call to setBrush()on line 24, so therest of the ellipses are filled with the brush color Line 26 calls setPen()to removethe pen from QPainter, so the ellipse on the right has no outline
It may happen that you need to draw a circle or an ellipse around a center pointinstead of the upper left corner To do this, simply subtract the radius from the center point (in each direction) to locate the upper-left corner:
p.drawEllipse(x - (w / 2),y - (h / 2),w,h);
Drawing Parts of Circles and Ellipses
There are three ways you can draw part of a circle or an ellipse The process is thesame as drawing a circle or ellipse, as in the previous example, except you mustalso specify a starting and ending angle
To specify which part of the circle or ellipse is to be drawn, it is necessary to ify the starting and ending angles The angles are measured in units of one-sixteenth
spec-of a degree If you are going to be entering hard-coded angles, Table 12-2 lists some
of the more commonly used values
Table 12-2
Comparison of Angle Measurement Units
Qt Units Degrees Radians
Trang 10286 Part II ✦ Step by Step
If you are going to be calculating the angles, most math software utilities use eitherdegrees or radians; you will need to convert back and forth The following state-ments will convert degrees and radians to the Qt scale:
angle = degree * 16;
angle = (radian * 180) / PI;
And these statements will convert Qt scale values to degrees and radians:
degree = angle / 16;
radian = (angle * PI) / 180;
Positive rotation is counterclockwise The zero-degree point is on the right Thestarting and ending angles are expressed in relative terms That is, the startingangle specifies the distance from the zero point that the drawing is to begin, andthe ending angle specifies the distance from the starting angle to the end of thedrawing Both numbers can be either positive or negative If the starting angle isless than the ending angle, the drawing occurs in the positive (counterclockwise)direction If the starting angle is less than the ending angle, the drawing occurs inthe negative (clockwise) direction
The following example demonstrates three different approaches to drawing an arc:
Trang 11That is, you choose the x and y coordinates of the upper-left corner of the bounding
box of the entire ellipse, even though you are only going to be drawing a portion of
it The starting angle is 0 and the ending angle is 4000, which is almost 270 degrees
Figure 12-13: Some ways to draw arcs,
pies, and chords
The call to drawArc()on line 27 creates the shape in the center of the first row ofFigure 12-13 Even though this figure is drawn with a QPainterthat has a brush,there is no filling because an arc is not a closed figure The call to drawArc()online 31 does not appear because the pen has been disabled and drawArc()doesnot use the brush
The call to drawChord()on line 24 draws the leftmost shape in the center row ofFigure 12-13 A chord is like an arc, except that it always draws a line between theend points of the arc to create a closed figure Because a chord is a closed figure,the calls to drawChord()on lines 28 and 32 both fill the enclosed area with thebrush color
Trang 12288 Part II ✦ Step by Step
The call to drawPie()on line 25 draws the leftmost shape of the bottom row ofFigure 12-13 A pie is like an arc, except that it always draws two lines between thecenter and the two end points to create a closed figure Because a pie is a closedfigure, the calls to drawPie()on lines 29 and 33 both fill the enclosed area with thebrush color
Rectangles with Rounded Corners
The QPaintermethod drawRoundRect() can be used to draw rectangles withvarying degrees of rounding on the corners The following example demonstratesthe flexibility of drawRoundRect(), which can be used to draw squares, rectangles,circles, and ellipses as well as rounded-corner rectangles The program draws anumber of shapes, as shown in Figure 12-14
Trang 13Calling one of the following two methods draws a rounded rectangle:
drawRoundRect(int x,int y,int w,int h)drawRoundRect(int x,int y,int w,int h,int xround,int yround)
The first four arguments define a rectangle The last two arguments (which bothdefault to 25) specify the roundedness of the corners in both the vertical and hori-zontal directions
Rectangle 1 in Figure 12-14 is drawn by the call to drawRoundeRect()on line 24
The first two arguments specify the x and y location of the upper left corner of
where the rectangle would be if it were not clipped off by being rounded The figure
is a square that is 50 pixels on a side, and the roundedness of the corners was
Trang 14290 Part II ✦ Step by Step
allowed to default at 25 in both the x and y directions This means that 25 percent
of the vertical distance and 25 percent of the horizontal distance will be used tocreate the rounded corners
Rectangle 2 is drawn by the call to drawRoundedRect()on line 27 Like rectangle 1,this call also produces a square, but the horizontal and vertical roundedness amountshave been set to 50 percent each instead of being allowed to default to 25 percent
Rectangle 3 demonstrates that setting the height and width to the same values, andsetting the roundedness to 100 percent, causes the entire length of the sides to beincluded in the curved portion; the result is a circle
Rectangle 4 is drawn on line 33 The vertical and horizontal roundedness are bothallowed to default to 25 percent, but because the rectangle is wider than it is tall,more pixels are involved in the horizontal direction than in the vertical direction,resulting in a curve that is not symmetrical
Rectangle 5 is drawn on line 36 to demonstrate the fact that setting one (or both)
of the roundedness values to 0 percent will cause the corner to be square In thisexample, the vertical roundedness is set to 50 percent, but it cannot be used tomake a curve because the horizontal setting is 0 percent, which forces the horizon-tal line to go all the way to the corner
Rectangle 6 is created on line 39 by setting the vertical roundedness to 100 percentand the horizontal roundedness to 30 percent
Rectangle 7 is drawn on line 42 with both the horizontal and vertical roundednessbeing set to 100 percent The result is an ellipse
Rectangle 8, drawn on line 45, is designed to have symmetrical roundedness — that
is, the same number of pixels are involved in the curve in both the vertical and zontal directions Because roundedness is expressed as a percentage, it is necessary
hori-to select a pixel value and then use it hori-to determine the percent in each direction:
xround = (100 * pixels) / height;
yround = (100 * pixels) / width;
Drawing Pixmaps and Text
You can draw all or part of a pixmap and define the font to be used to draw anytext The following example draws an entire pixmap, then part of a pixmap, andthen writes text on top of the drawing, as shown in Figure 12-15
Trang 15Chapter 12 ✦ Drawing and Painting with QPainter
Figure 12-15: Pixmap with text
Trang 16292 Part II ✦ Step by Step
The constructor, beginning on line 17, creates the logopixmap from the data file
logo.xpmincluded on line 7 It then sets the display window to a fixed size
The call to drawPixmap()on line 27 paints the entire logopixmap The upper-leftcorner of the pixmap is located 10 pixels over and 10 pixels down from the upper-left corner of the widgets Because no other arguments were specified, the entirepixmap is copied to the target location
The call to drawPixmap()on line 28 paints only a portion of the logopixmap Thismethod first extracts a rectangular area from the pixmap and then paints the extrac-tion to the target window The last four method arguments determine the extractedarea by specifying the upper left corner and the height and width The area to beextracted is 60 pixels from the left and 50 pixels from the top of the pixmap, its width
is 100 pixels, and its height is 80 pixels The first two arguments specify where thepixmap is to be drawn — its upper left corner is placed 250 pixels from the left and
80 pixels from the top
Trang 17Chapter 12 ✦ Drawing and Painting with QPainter
Every QPainterobject contains a QFontobject that it uses to draw text You canuse this default font, create a new font, or, as in this example, modify the existingfont The call to font()on line 30 retrieves the QFontobject from the QPainter
object In this example, a call is made to setPointSize()on line 31 to make thetext a bit larger The call to setFont()establishes the new font as the one that will
be used to paint all of QPaintertext
See Chapter 10 for more information about creating and modifying fonts
Line 34 calls setPen()to make the text appear as white (instead of the defaultblack), and the call to drawText()on line 35 paints the text on the window, withthe left end of the text baseline 200 pixels from the left and 250 pixels from the top
of the window
Summary
The QPaintermethods described in this chapter should supply you with over 90percent of the graphics you will ever need With only two objects that render graph-ics, a QPenand a QBrush, you can create anything you want If you need extremeflexibility, you can use the pixel-by-pixel approach to get exactly what you want
This chapter explored QPaintermethods that can be used to accomplish the following:
✦ Draw one pixel at a time to the window, or define objects to hold arrays of pixels and draw them all at once
✦ Draw lines, in multiple colors and various widths, from any point to any otherpoint Also, multisegmented lines can be drawn either one at a time or all atonce
✦ Draw ellipses and circles in their entirety, or draw only a portion of the curve
You can use different styles to fill and slice the circles and ellipses
✦ Draw pixmaps — in their entirety or select a rectangular area
The following chapter builds on the information in this chapter Some methods inthe QPainterobject can be used to manipulate graphics to change their shape,angle, and colors You can also use some very specialized graphics objects to dothings like record a sequence of graphics commands for later playback
Cross-Reference
Trang 19Graphics Manipulation
The previous chapter demonstrated some of the
funda-mentals of drawing and painting graphics to windows,and this chapter demonstrates some of the special capabili-ties in KDE and Qt for manipulating graphics
Because everything displayed in a widget is graphic, many ofthe techniques described in this chapter can be used to mod-ify any graphic content Probably the most useful informationpertains to the processes for rotating and positioning images,but there is quite a bit more For one thing, depending on thecapabilities of your printer, it is a very simple process to print
a graphic image in color or in black and white It is possible
to reshape graphics scaling and shearing, or even to modifyimages by making changes to bit values of each pixel And ani-mation can be performed by drawing one frame after anotherand displaying the frames in a controlled, timed sequence
Using a QPicture to Store Graphics
Anything that can be drawn to the window of a widget canalso be drawn to a QPictureobject The QPictureobject canthen save the drawing instructions to a disk file, and another
QPictureobject can read the file and execute the drawinginstructions There are a number of uses for this, includingthe capability to store complicated drawings and transmitgraphics from one system to another The following programcreates a simple drawing and saves it to a disk file:
capabilitiesScaling, clipping,shearing, rotating,and translatinggraphicsAnimating sequences
of drawn shapes andfigures
Manipulating pixelcolors at the bit level
Trang 20296 Part II ✦ Step by Step
This program creates graphics, but does not display a window Instead, it uses a
QPictureobject as the target of the drawing, and the QPictureobject records all
of the instructions and then writes them to a disk file
On line 10, the KAapplicationobject appis created to define this as a KDE cation because a QPainterobject can only be used inside a KDE application Lines
appli-11 and 12 create the QPainterobject that is used to do the drawing, and the
QPictureobject that records the QPainterinstructions
Line 14 begins the graphics session by calling begin() The object of the drawing
is the QPictureobject, rather than a widget Lines 15 through 20 set the QPainter
pen and brush values, and call the methods to do the actual drawing The QPicture
object records each of these method calls The drawing session is halted by the call
to end()on line 21 The call to save()on line 22 creates the file named recplay.qpicthat contains all of the drawing instructions
Trang 21Chapter 13 ✦ Graphics Manipulation
14
15 #endifPlayback
Figure 13-1: The playback of previously recorded
graphics commands
Trang 22298 Part II ✦ Step by Step
The previously recorded graphic instructions are painted using a QPainterobject,
so there is nothing to prevent your program from embellishing the recorded tions with some of your own For example, the image shown in Figure 13-2 resultsfrom changing the paint commands in the paintEvent()method to the following:
instruc-if(picture.load(“recplay.qpic”))p.drawPicture(picture);
p.setBrush(QColor(“black”));
p.drawRect(110,110,230,30);
Figure 13-2: Combining playback and current
graphics commands
Painting Graphics to a Printer
It is just as easy to paint pages on the printer as it is to paint windows on the display.The following example program displays the same graphics window as the one previ-ously shown in Figure 13-1, except for the addition of a Print button in the lower rightcorner Selecting the button will cause the dialog shown in Figure 13-3 to appear, allow-ing the user to make decisions about the print If the user selects the OK button, thegraphic is printed
Trang 24300 Part II ✦ Step by Step
Figure 13-3: The user options that control printing
The constructor, on line 15, sets the size of the window and installs a button in thelower right corner The slot method printSlot()is attached to the button
The paintEvent()method on line 24 draws graphics on the window of the widget
The slot method printSlot()on line 37 prompts the user for printer settings, and
if the user selects the OK button in the dialog shown in Figure 13-3, it draws thegraphics on a page of the printer The call to setup()on line 42 pops up the dialog,
Trang 25Chapter 13 ✦ Graphics Manipulation
and a return value of TRUEindicates that the print should proceed Line 43 calls
begin()to attach the QPainterobject to the printer The graphics are then drawnjust as they would be if they were being drawn to the screen
The call to end()on line 50 ends the drawing and sends the graphics instructions
on to the printer This call also closes the output to the printer and sends the page(or pages) to the spooler for printing If, in the middle of your printing, you wish toeject the current page and start with a new one, you can do so with the followingmethod call:
print.newPage();
At any point during the printing process, you can delete all the pages before theyare sent to the spooler as follows:
print.abort();
Printer Information and Control
While it is just as easy to draw to a printer as it is to a window, you need to be able
to find out information about things like the size of the page and the number of dotsper inch The following example program displays some of the basic printer infor-mation in the window shown in Figure 13-4 You can run this program and use thepop-up dialog to modify the printer settings and see the values change
Figure 13-4: Some of the values describing a printer
Trang 26302 Part II ✦ Step by Step
Trang 28304 Part II ✦ Step by Step
Trang 29Chapter 13 ✦ Graphics Manipulation
The slot method printSetupSlot()on line 24 pops up a printer-configuration log, like the one shown previously in Figure 13-3, that can be used to modify theuser-configurable settings for the printer
dia-The paintEvent()method on line 24 creates a window that displays a list of thecurrent printer descriptive information and settings Some of the information isretrieved from a QPaintDeviceMetricsobject, and some is retrieved directly fromthe QPrinterobject itself
The printer name, on line 36, is the name the user selected from the list of availableprinters If the user has not selected a printer, a zero-length string is returned from
printerName()and any printed output will be directed to the default printer If theoutput has been directed to a file instead of a printer, the call to outputToFile()
on line 44 returns TRUEand a call to outputFileName()will return the name of thefile When directed to a file, the printed data is sent to the file in postscript format
The call to orientation()on line 51 indicates whether the output will be printed
in portrait or landscape mode If portrait, the output is taller than it is wide If scape, it is wider than it is tall The default is portrait
land-The call to numCopies()on line 63 returns a count of the number of copies to beprinted The default is 1
The call to colorMode()on line 63 indicates whether the printing is to be done incolor or grayscale This may not always be accurate, because many printers arecapable of accepting color print data, but will convert it to shades of gray for print-ing In any case, it is always safe to print color data because, if necessary, it will beconverted to shades of gray either by the printing software or by the printer itself
The page width and height on lines 71 and 76 are a measure of the printable area Ifyou need a height and width value to render graphics, as you would if painting graph-ics to a window, you can use these numbers in conjunction with the margin values andthe full-page indicator If the call to fullPage()on line 80 returns TRUE, the heightand width extend to the edges of the paper If the fullPage()method returns FALSE,the height and width are the measurements inside the margins You can set the printer
to full-page mode by calling printer.setFullPage(TRUE), or you can set the pagesize to adjust for margins (the default) by calling printer.setFullPage(FALSE)
The margin values, retrieved by calls to margins()on lines 88 and 93, are eitherthe actual margin values when not in full-page mode, or the suggested marginswhen in full-page mode
Unlike a window, which has no exact fixed width and height, a printer has a fixedphysical width and a fixed number of dots per inch, so these values can be deter-mined However, the numbers are not entirely trustworthy because your printermay not report the values to your computer, or your printer configuration could be
in error, or the user could have chosen to print to a file In any case, the width andheight of the page are reported in millimeters, on lines 98 and 103; and the number
of dots per inch is reported on lines 108 and 113
Trang 30306 Part II ✦ Step by Step
The total number of colors (or number of shades of gray) per dot is returned fromthe call to numColors()on line 118 The same information is also reported as thenumber of bits per dot with the call to depth()on line 123
Fitting a Drawing to a Window
You can establish your own coordinate system, use it to draw graphics in a window,and have your coordinate system automatically translated to that of the actual win-dow The following example shows how this can be done:
Trang 31Figure 13-5: Resizing the window resizes the graphics.
Fitting a Drawing to a Subwindow
The setWindow()method of the previous example can be used in conjunction withthe setViewport()method to scale drawing and painting to subwindows within awindow The following example maps the same drawing to four subwindows within
a window and results in the display shown in Figure 13-6
Figure 13-6: The same graphic appearing
four times in the same window
Trang 32308 Part II ✦ Step by Step
Trang 33and paintFigure()to paint the window shown previously in Figure 13-6.
The call to setViewport()on line 22 specifies that all drawing is to be done in theupper left corner, at location (0,0) in the window, and that the drawing is to be lim-ited to an area 100 pixels wide by 50 pixels high The call to paintFigure()on line
23 does the actual painting of the pixels In the same fashion, three other shapesare drawn to view ports (subwindows) by first calling setViewport()to specify asubwindow and then calling paintFigure()to draw the graphics
The method paintFigure()beginning on line 31 draws the graphic It starts out
by calling setWindow()on line 33 to specify that the window is to be drawn to asquare area with a scale of 300×300 pixels, with its origin at the upper-left corner
The graphic is then built up in the 300×300 square by calling the primitive drawingmethods drawRoundRect(), drawEllipse(), and drawPie() The physical loca-tion of the pixels, and the aspect ratio of the resulting picture, was set by the call to
setViewport()before the call to paintFigure() This allows the paintFigure()
method to calculate and render graphics independently of the actual pixel positions
Clipping
It is possible to limit a drawing to a specific region That is, everything drawn side the region is clipped off and not drawn The following example draws the sameellipse using three different brushes, but the second and third ellipses are clipped
out-so that the original ellipse is still partially visible:
ClipArea
1 /* cliparea.cpp */
2 #include <kapp.h>
3 #include <qpainter.h>
Trang 34310 Part II ✦ Step by Step
Trang 35Chapter 13 ✦ Graphics Manipulation
Lines 28 through 30 draw the area of vertical lines in the upper-left corner of theellipse The brush is set to a black VerPattern, resulting in the vertical lines; andthe call to setClipRect()on line 29 limits the drawing to only the rectangular areathat is 70 pixels wide by 70 pixels tall, and has its left corner at the location (30,30)
Although the call to drawEllipse()on line 30 attempts to draw the entire figure,the actual drawing is restricted to the clipped area Also, because the brush patternallows the background to show through, a portion of the original ellipse is also visible
The same technique is used to paint the triangular area on the right side of theellipse In this case, the clipping region is defined by the call to setClipRegion()
on line 36 The QPointArraynamed pacontains only the three points of a triangle,but it could contain as complex a polygon as you would like to define
Also, because you can define only one clipping region, defining a new clippingregion deletes the previous one If you wish to disable the clipping region, you cancall the setClipping()method as follows:
p.setClipping(FALSE);
Scale
A drawing can be scaled to larger and smaller sizes by changing the coordinates in
QPainterprior to drawing the picture The following example shows the result ofchanging the scale and drawing a pixmap:
Trang 36312 Part II ✦ Step by Step
The XPM file included on line 6 is converted to a QPixmapon line 19 The pixmap is
72×72 pixels The call to drawPixmap()on line 26 draws the pixmap in its normalsize in the upper-left corner of the window, as shown in Figure 13-8
The default scale values are 1.0 along both the x and y axes To change the value,
the scale()method is called with multipliers of both of the values The call to
scale()on line 27 doubles the scale in both the x and y directions, so the call to
drawPixmap()on line 28 draws a pixmap twice as large as the first one Noticethat, on the call to drawPixmap(), in order to offset the drawing 72 pixels to theright, a coordinate value of 36 is needed because it is also being scaled to twice itsnormal size The call to scale()on line 29 makes no change to the scale along the
x axis because it multiplies the current scale setting by 1.0, leaving it at 2.0, but
doubles the scale along the y axis, causing the vertical scale factor to become 4.0.
The call to drawPixmap()on line 30 draws the pixmap twice as wide and four times
as high as the default
Trang 37Chapter 13 ✦ Graphics Manipulation
Figure 13-8: A pixmap drawn to three
different scales
Shear
To shear a figure is to skew it so that the x axis no longer lies along the horizontal plane, or the y axis is no longer vertical, or both Increasing the shear value of the y axis moves the bottom of the y axis to the right, while increasing the shear value of the x axis moves its right end downward The amount of the movement is deter-
mined by the size of the window Negative shear factors move the axes in the
oppo-site directions For example, if a window is 100 pixels wide, an x axis shear value of
0.5 will move the right side of any drawn figure 50 pixels down; a shear value of 1.0will move the right side 100 pixels down; and a shear value of -1.0 will move theright side up 100 pixels
The following example shows the result of shearing in both the x and y directions.
Figure 13-9 shows the same figure drawn with (from left to right) an x shear factor
of 1.0, no shearing, and a y shear factor of 1.0
Figure 13-9: Vertical shear, no shear, and