Next Previous Table of Contents
The first step when creating an application based on the Document-View model should always be to think what kind of data the
application has to manage. This decides how the view class will look like but especially how the document class will read and write data
to and from files and offer methods to manipulate the data. As KScribble will be a simple drawing application that operates on
graphical data, we will use the Qt class QPixmap
for storing our paintings while it is edited. QPixmap
also offers
simple methods to read and write pictures into files, so the serialization of the document data is done in just two lines, one for
reading and one for writing. Further, we need to define a pen that draws into a document, set it's width and color and make it
available for the view class to retrieve the pen - actually you want the view offering the drawing methods, but the document as the
central element for all views has to hold the pen originally, because two views of the same document would otherwise use different
pens!
Therefore to define how our document class should work, we will add one instance of QPixmap
, one of QPen
and edit the
methods newDocument()
, openDocument()
and saveDocument()
.
Open the file kscribbledoc.h
by selecting it in one of the fileviewers or by a click on the classviewer over the class
KScribbleDoc
. Then add the lines marked with -> from the following code snippet:
-> #include <qpixmap.h> -> #include <qpen.h> class KScribbleDoc { -> protected: -> QPen currentPen(){ return pen;}; -> int penWidth() -> { return pen.width(); } public slots: void updateAllViews(KScribbleView *sender); protected: -> QPixmap buffer; private: -> QPen pen; /** the modified flag of the current document */ bool modified;
As you see, we added pen and buffer as well as currentPen()
and penWidth()
. As pen is declared private, we offer a
possibility to retrive the pen as well as the pen width. As these are already implemented within the classdeclaration, we don't have to
add them to the implementation file, where we're turning to now.
Select the method newDocument()
in the KScribbleDoc
class to jump to the method declaration. Here, we're only adding
one line, marked with the arrow:
kscribbledoc.cpp bool KScribbleDoc::newDocument() { ///////////////////////////////////////////////// // TODO: Add your document initialization code here -> pen=QPen( Qt::black, 3 ); ///////////////////////////////////////////////// modified=false; return true; }
This initializes the pen with the color black and width of 3 pixels; the QPen
class has some more constructors, but this one lasts our
needs here.
What is left to do is to define how to open and save our pictures. This is done in the according methods:
bool KScribbleDoc::openDocument(const QString &filename, const char *format /*=0*/) { QFile f( filename ); -> //if ( !f.open( IO_ReadOnly ) ) -> // return false; ///////////////////////////////////////////////// // TODO: Add your document opening code here -> if(!buffer.load( filename, "PNG" )) -> return false; ///////////////////////////////////////////////// -> //f.close(); bool KScribbleDoc::saveDocument(const QString &filename, const char *format /*=0*/) { QFile f( filename ); -> // if ( !f.open( IO_WriteOnly ) ) -> // return false; ///////////////////////////////////////////////// // TODO: Add your document saving code here -> if(!buffer.save( filename, "PNG" )) -> return false; ///////////////////////////////////////////////// -> //f.close();
Add the lines marked with the arrow again to your code. What we did here is to comment out the passages where the file
filename
is opened, because that is done automatically by the load and save methods of QPixmap
, which we add instead. Other
documents may open a file and read in its contents such as text lines or whatever, so the QFile
methods are already present in the
codeframe. As save()
and load()
return a boolean value if the operation was successful, we're returning false if not,
so the rest of the framework gets a return value and can give out warnings if the operation was not successful.
The load()
and save()
methods now are already provided in QPixmap
. They require the filename and the format as
argument; the source framework on the other hand does not call the document methods with the format yet. If only one format is
used, it lasts to set the format here. other methods could detect the format for example- but we will turn to this later. For now,
we're using "PNG" as format; see QImageIO
for more details about the image formats that can be opened.
Now we're already finished defining our document structure. The QPixmap
buffer serves us as a buffer storing the original picture
contents while we're working on it, the pen is a valid pen for all views connected to the document. Note that the initialization of the
pen is done in newDocument()
. This method is always called after the constructor within the framework internally, so you
should add document instances initializations there as we did with the pen.
In the next chapter we will turn to the view class to define how the view shall cooperate with the user as well as how it accesses the document- and then we'll be ready to paint !
Next Previous Table of Contents