0% found this document useful (0 votes)
27 views

Notes-6 Cos3711 Summarised DP

Uploaded by

Elijah Nhlanhla
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views

Notes-6 Cos3711 Summarised DP

Uploaded by

Elijah Nhlanhla
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Structural = how organize objects + connect them

Design Patterns Libraries


Behavioral = how organize code
Pre-compiled programming codes
ready for use
Creational = how organize code to manage object creation
Groups code modules, reusable
Efficient and elegant
solutions to common
problems Included in project with directive #include
Framework is large colletion components and System program caller linker establish link between
conventions documented public API program and library code at run time
Qt is a framework – framework implemented with design
lib file ease job of linker – contains compiled/object files,
Framework and patterns
ease linking process of library items and program code
Design Pattern Design patterns efficient solution to common problems

Responsible reading and ANTIPATTERNS


writing objects
Serializer Pattern Common used programming practices/solutions to recurring
programming problems that is ineffective/inefficient
QTextStream = read + write human-readablefiles
1) Software Design antiPattern
> Input kludge – failing handling invalid input
QDataStream = read + write structured data binary > Interface bloat – interface powerful/complicated, hard to reuse
> Race hazard – fail see consequence order of events
Client
2) Object-oriented design antiPattern
> Circular dependency – mutual dependencies between objects
> God object – too much information/responsibility
3) Programming antiPattern
Class1Reader Class1Writer
Class1 > Hard coding – embedding assumptions
+read(Class1) +writer(Class1) > Magic numbers – unexplained numbers
> Magic strings – literal strings
4) Methodological antiPattern
> Copy + paste programming – existing code
> Reinvent the (square) wheel – existing solution
Using reflective programming, can write general-purpose
operations work on classes of varied structures.
QMetaObject Meta object describe structure of another object
To make class reflective:
MetaObject Pattern (Reflective pattern): Inherit from QObject
information about properties and methods of QObject Include Q_OBJECT macro
Q_PROPERY(QString name READ getName WRITE setName)
Q_PROPERTY macro Describe QObject Properties
Access data members:
> Direct (getters and setters) – faster more efficient
> Indirect (QObject / QMetaObject interface) – more reusable code

Q_PROPERTY (type name READ getFunction [WRITE setfunction] [RESET resetFunction] [NOTIFY ntifySignal])
[. . . .]
Class Customer: public QObject{
Q_OBJECT
Customer::Customer(const QString name, QObject * parent)
Q_PROPERTY (QString id READ getID WRITE setID NOTIFY valueChanged)
:QObject(parent){
Q_PROPERTY (QString name READ getName WRITE setName)
setObjectName(name);
Q_PROPERTY (CustomerType type READ getType WRITE setType)
}
Q_PROPERTY (Qdate dateEstablished READ getDateEstablished) //read-only
public:
Void Customer::setId(const QString &newId){
enum CustomerType {Corporate, Individual,
if (newId !- m_id) {
Educational, Government};
Qstring oldId = m_id;
Q_ENUMS(CustomerType);
m_id = newId;
emit valueChanged( id newId, oldId);
explicit Customer (const QString name = QString(),
}
QObject * parent = 0);
Void Customer::setType(CustomerType theType){
QString getId() const {
if (m_Type != theType) {
return m_id;
CustomerType oldType = m_type;
}
m_Type = theType;
}
QString getName() const {
return m_name;
Void TestCustomerProps::test() {
}
Customer cust;
cust.setObjectName( Customer
CustomerType getType() const {
cust.setName( Falafal
return m_type;
cust.setType( Government //enumproperty as string
}
QString originalId =
private:
cust.setId(orifinalId);
QString m_id, m_name;
QVariant V = cust.propert id
CustomerType m_type;
QString str = v.toString();
};
return;
[. . . .]
}
[. . . .]

/* Method for setting enum values from Strings */


Void Customer::setType (Qstring newType){ 1
static const QMetaObject* meta = metaObject(); 2
static int propindex = meta->indexOfProperty( type
static const QMetaProperty mp = meta->property(propindex); What kinds of information can you obtain from a QMetaObject?
className(), which returns the class name as a const char*
QMetaEnum menum = mp.enumerator();
const char* ntype = newType.toAscii().data(); 3
superClass(), which returns a pointer to the QMetaObject of the base class if there
CustomerType theType = is one (or 0 if there is not)
static_cast<CustomerType>(menum.keyToValue(ntyp)); methodCount(), which returns the number of member functions of the class
method(index), which returns the meta-data for the method with the given index
if (theType != m_type) { 4 propertyCount(), which returns the number of properties in this class, including base
CustomerType oldType = m_type; class properties.
m_type = theType;
property(index), which returns the meta-data for the property with the given index.
emit valueChanged( type theType, oldType);
} What Qt classes are used to do data reflection?
} QMetaObject, QMetaProperty, QSqlDatabase::tables, QSqlRecord, Qvariant
How does the QMetaObject code for each of your QObject-derived classes get generated?
moc generates QMetaObject classes to support properties, signals and slots.
1 Overloaded version accept string as argument. Set Normally, you do not run moc directly. It is run automatically by make on the
value -1 if unknown. header files listed in HEADERS which use the Q_OBJECT macro.
2 Static locals, initializations happen only once. What are the advantages of using property() and setProperty() over direct getters and
3 Executed each time setters?
4 Check if valueChanged signal needed Q_PROPERTY macros make it possible for moc to generate code for QObject's
property() and setProperty() member functions. The advantage of using these
functions is that client code can determine which properties are available by
iterating through QMetaProperty objects of the QMetaObject corresponding to that
QDataStream out(...);
QVariant v(123); // The variant now contains an int
class.
int x = v.toInt(); // x = 123 What does the property() function return? How do you obtain the actual stored value?
out << v; // Writes a type tag and an int to out property() returns a QVariant, which is a union wrapper around every possible basic
v = QVariant("hello"); // The variant now contains a QByteArray type, and also several Qt classes/types. With QVariant, you can ask for its type()
v = QVariant(tr("hello")); // The variant now contains a QString
int y = v.toInt(); // y = 0 since v cannot be converted to an int
and convert to the actual value<>(). Benefits are most apparent when implementing
QString s = v.toString(); // s = tr("hello") (see QObject::tr()) script engines or developer tools. It becomes possible to define "handle anything"
out << v; // Writes a type tag and a QString to out kinds of functions without using anything but the QObject interface to read and
... write values.
QDataStream in(...); // (opening the previously written stream)
in >> v; // Reads an Int variant
Explain how it is possible to add new properties, acquired at runtime, to a Qobject
int z = v.toInt(); // z = 123 setProperty("propName") sets a dynamic property for that object even if it is not
qDebug("Type is %s", // prints "Type is int" declared as a Q_PROPERTY
v.typeName()); Explain how dynamic properties can be serialized
v = v.toInt() + 100; // The variant now hold the value 223
v = QVariant(QStringList()); They are stored in a QVariantMap, which can be serialized via a QDataStream.
QMetaObject
Class Person: public Qobject
{
Q_OBJECT
Qt support reflective programming via QMetaObject Q_PROPERTY(Qstring name READ getName WRITE setName)
Q_PROPERTY(Qdate birth READ getBirthDate WRITE setBirthDate)
public:
Provides generic interface through which state of any Qobject Person();
accessed and manipulated Person(Qstring n, Qdated);
Qstring getName()const;
Qdate getBirthDate()const;
Instance of QMetaObject class used as mirror reflect and void setName(Qstring n);
change stated of Qobjects without manupulating Qobject void setBirthDate(QDate d);
directly private:
QString name;
Qdate birthDate;
};
Qobject
Person * person = newPerson;
Person Product writeToFile(person);
-name:Qstring -name:Qstring Product* product = new Product;
-birthDate:QDate writeToFile(product);
-price:double
+Person() +Product() writeToFile(Qobject *obj){
+Person(QString, Qdate) +Product(QString, double) QFile file( dat.txt
+getName():Qstring +getName():Qstring file.open(QIODevide::Append);
+getBirthDate():Qdate +getPrice():double QTextStreamtoFile(&file);
+setName(Qstring) +setName(Qstring) const QMetaObject *mo = obj->metaObject();
+setBirthDate(Qdate) for (int i=mo->propertyOffset(); i<mo-propertyCount();i++)
+setPrice(double)
{
const QMetaProperty prop = mo->property(i);
QString name = prop.name();
writeToFile(Qobject*);
QVariant value = prop.read(obj);
Qstring valStr = value.toString();
toFile << name << valStr << endl;
}
file.close();
}
Models and Views Separate underlying data class (model) from GUI (view)
Example QFileSystemModeluser QTreeView:
#include <QtGui>
Standard Widgets ->use data as part of widget Standard Widgets: int main(int argc, char *argv[]){
• Two copies data: one outside widget, one inside Qapplication app(argc, argv);
• Synchronize both QFileSystemModel model;
View • Tight coupling present data, hard write unit test
model.setRootPath(
QTreeView tree;
tree.setModel(&model);
Data tree.setSortingEnabled(true);
tree.header()->setResizeModel(QHeaderView::
• Separate model from view – reduces complexity ResizeToContent);
View class operate external data (model) • Different maintenance imperatives – easier tree.resize(640, 480);
maintain both kept separate tree.show();
• Possible maintain different, consistent views of return app.exec();
View
same data }
• Different, consistent views of same data
setModel() • Do not store data
• Do not know data structure

Model
Data

MVC consists of three kinds of objects.


1) Model = application object
2) View = screen presentation
3) Controller = defines way user interface reacts to user input
QFileSystemModel in a
QTreeView QFileSystemModel is already populated with data, so we can simply
create one, create a view, and view->setModel(model).

#include <QtGui>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QFileSystemModel model;
model.setRootPath("/");
QTreeView tree;
tree.setModel(&model);
tree.setSortingEnabled(true); 1
tree.header()-
>setResizeMode(QHeaderView::ResizeToContents);
tree.resize(640, 480);
tree.show();
return app.exec();
}

//1 - Enable HeaderView sort buttons.

Qt provides its model-view architecture to separate models and view. In this architecture a number of abstract and concrete model and view classes are
provided. Though this architecture supports the separation of model/logic from the views, it does not provide controller classes like the classic MVC pattern.
Qt s model-view architecture uses signals and slots for the communication between models and views.
A model class in Qt either has the data or communicates with the data source. In order to make use of Qt s model-view architecture one has to either use
the built-in, concrete model or view classes or implement a model or view class derived from model/view interfaces provided in Qt. In order to make use of
the architecture the view has to be set up with a model. In other words, view has a model and not the other way around.
In a sense, Qt replaces the controller in its model-view architecture with delegates that are
responsible for the rendering/display and editing of model data in a view.
int main (int argc, char* argv[]){

Validate Regular Expression QApplication app(argc, argv);


QLineEdit e;
e.setIntputMask( - - -
e.show();
return app.exec();
QLineEdit validate input: }
A > ASCII alphabetic character
N > ASCII alphanumeric character int main (int argc, char* argv[]){
X > ASCII any character QApplication app(argc, argv);
D > ASCII nonzero digit QLineEdit e;
QIntValidator *v = new QIntValidator(0,100);
9 > ASCII digit e.setValidator(v);
# > Hexadecimal digit e.show();
B > Binary digit return app.exec();
}
Validators = attached to input widgets
1) QDoubleValidator = floating point
2) QIntValidator = integer
3) QRegExpValidator = text regular expression

Regular Expression
Special characters
. any character
\n newline QLineEdit e;
\f form feed QRegExp re( a-zA-Z][_a-zA-Z0-9]+
\t tab QRegExpValidator *v = new QRegExpValidator(re);
\xhhhh hex Chracter Sets: e.setValidator(v);
\S white space e.show();
Quantifiers \S non-whitepace
+ 1 or more \d digital 0 to 9 Consist 4 digits (0-9):
? 0 or 1 \D non-digital d{4}
* 0 or more \w any word character (letter/
{i, j} at leat i, no more than j digit/underscore) Consist 6 character, forst 3 alphabetic, last 3
\W non-word character digits
A-Za-z]{3}[0-9]{3}
[AEIOU] match A, E, I, O, U
[a-g] range from a to g Minimum 4, max 6 characters, except0, z and Z
[^xyz] except x, y, z zZ]{4,6}
Three ways parse XML: QT+ - xml SAX
Qt s XML module:
Parsing Xml 1) SAX (Simple API for XML) – parse event-driven
2) DOM (Document Object Module) – tree-style parse
QXmlReader QXmlContentHandler
3) Stream-style parsing with QXmlStreamReader +parse() +startDocument()
+endDocument()
Each <tag> must have closing </tag>
+startElement()
Or selfclosing <br/> NB: Case-sensitive
+endElement()
QXmlSimpleReader +characters
Tags with attributes:
<library>
<book title = Computer Algorithm pages = • Event driven
<book title = C++ unleashed pages = • Low-level QXmlDefaultHandler
</library> • Sequential-access while parsing document
• Any file size
Tags with text: • Forward direction
<library> MyHandler
<book>
<title>Computer Algotithm</title>
<pages>688</pages>
Myhandler.cpp
</book>
QTextStream cout(stdout);
<book>
<title>C++ unleashed</title>
bool MyHandler::startDocument(){
<pages>918</pages>
indent =
</book>
return TRUE;}
</library>
bool MyHandler::characters(const Qstring & text){
QString t = text;
#include <QXmlDefaultHandler> cout << t.remove( n
class Qstring;
class MyHandler:public QXmlDefaultHandler{ Bool MayHandler::startElement(const Qstring & namespaceURI,
public: const QString & LocalName,
bool startDocument(); const QString & qName,
bool startElement(const Qstring & namespaceURI, const QXmlAttributes & atts){
const QString & LocalName, QString str = QString n%1\\%2).arg(indent).arg(qName);
const QString & qName, cout << str;
const QXmlAttributes & atts); if (atts.lenght()>0){
bool characters (const QString & text); QString fildName = atts.qName(0);
bool endElement (const QString & namespaceURI, cout << QString
const QString & localName, .arg(fieldName).arg(fieldName);
const QString & qName); }
private: cout <<
QString indents; indent +=
}; return TRUE;
}
Write to file: (open filem create text stream, call toStrin() method of DOM document)
int main (int argc, char **argv){
DOM QApplication a (argc, argv);
QDomDocument doc AdBookML
QDomElement root = doc.createElement adbook
doc.appendChild(root);
• XML elements as objects in tree structure
• File in memory, limit RAM Contact c;
• Random access
• Not handle parse errors c.name = Kal
• Creating documents c.eMail = [email protected]
c.phone =

Writing using DOM: root.appendChaild(ContactToNode(doc, c));


1) Create document (QDomDucument)
2) Create root element QFile file c:/qt/text/xml
3) for each contact, put in document if (file.open(Qfile::WriteOnly))
4) Write result to file return -1;
QTextStream ts(&file);
ts << doc.toString();
Reading using DOM: Reading file:
1) Create DOM document from file file.close(); QDomDocument doc adBookML
2) Find root Qfile file test.xml
3) Find children (elements) return 0; if (!file.open(IO_ReadOnly)
4) Find attributes } return -1;
file.close;
Create Document:
QDomDocument doc adBookML Find root element:
QDomElement root = doc.documentElement();
Create root element: if (root.tagNam() != adbook
root element point to start return -3;
root element called adbook
QDomElement root = doc.creeateElement( adbook Find element, check attributes:
doc.appendChild(root); QDomNode n – root.firstChild();
while (!n.isNull()){
Each contact put in document: QDomElement e = n.toElement();
QDomElement ConstactToNode( QDomDocument &d, const Contact & c){ if (!e.isNull()){
QDomElement cn = d.createElement( contract if (e.tagName() == contact
cn.setAttribute( name c.name); Contact c;
cn.setAttribute( phone c.phone); c.name = e.attribute( name
cn.setAttribute( email c.eMail); c.phone = e.attribute( phone
return cn; c.eMail = e.attribute( email
} }
}
n = n.nextSibling();
}
Creational Patterns: Manage object creation during runtime, manage object deletion
Design Patterns
Factory Method

Product uses Factory ...


Product = FactoryMethod()
FactoryMethod(): Product
...
Operation()

ConcreteProduct

ConcreteFactory

create FactoryMethod():product return newConcreteProduct

Bread AbstractBreadFactory Client


uses
- Bread *myBread
+makeBread(QString):Bread
+bake()

BreadFactory
WhiteBread
+ makeBread(Qstring):Bread

BrownBread

WholewheatBread

create
Abstract Factory Pattern

AbstractFactory AbstractProductA Client


createProductA()
createProductB()
ProductA1 ProductA2

ConcreteFactory2 ConcreteFactory1
AbstractProductB
createProductA() createPRoductA()
createProductB() createProductB()

ProductB1 ProductB2
Class has only one instance, accessed via global access point
Singleton Make constructor Private, creating one instance

Class A {
public:
static A* getInstance();
private:
A();
static A* onlyInstance;
}

A*A::onlyInstance = NULL;
A::A(){}
A*A::getInstance(){
if(onlyInstance == 0)
onlyInstance = new A();
return onlyInstance;
}
Object storing snapshot of internal state of another object
Memento Pattern
Object state restored, allow undo/rollback operation

Originator
Object know how to save itself

Memento Object written and read by originator

Caretaker Object holds memento for originator

state = m -> getState()

Originator Memento Caretaker

setMemento(Memento m) getState()
createMemento() setState()

state state

Return new Memento(state)


Memento Stares state of Originator • Role of Caretaker store Memento, not allowed access state of Originator.
• Achieved by making getState(), setState() and constructor of Memento provate,
Caretaker cannot access state of Originator.
Caretaker Keep Memento • Originator need able access construcotr, getState() and setState() of Memento.
Achieved making Originator friend of Memento.

Class Memento
{
public:
private: friend class Person;
Memento();
QStringList getState();
void setState(QStringList s);
QStringList state;
};

Memento Person::createMemento() const


{
QStringList state;
state << name << birthDate.toString();
Memento mem;
mem.setState(state);
return mem;
}

Void Person::setMemento(Memento m)
{
QStringList s = m.getState();
name = s.at(0);
birthDate = QDate::fromString(s.at(1));
}

int main(int argc, char *argv[])


{
Person p( John Qdate(1990,12,25));
//create memento
Memento caretaker = p.createMemento();
//change Person p
//restore Memento
p.setMemento(caretaler);
}
Unified interface to set of interfaces in subsystem
Façade Pattern
Defines higher-level interface making subsystem easier use
QProcess Qthread
Runs different program Runs same process, share
In same process, separate
memery
code, share memory with
other threads
Concurrency
Communicate with child Share memory and code Similar in concept: start() function cause execution, fork (two things happening
Process via streams with peer threads. Sync
(stdin, stdout stderr) locks, wait conditions,
Pass data using command mutexes, semaphores
Line arguments

Managed by operating Managed by process


system

QProcess: class for starting and controlling other process


Derived from QObject using signals and slots
#include <QObject>
#include <QProcess>
class LogTail: public Qprocess {
Q_OBJECT
public: LogTail (Qstring fn=Qstring());
~LogTail();
signals: void LogString()
public slots: void LogOutPut();
};

LogTail::LogTail (Qstring fn){


connect (this SIGNAL (readyReadStandardOutput()), this SLOT (logOutput()));
QString argv;
argv << -f fn;
start tail argv);
}

LogTail::~LogTail(){
terminate();
}
• QThread class provide platform-independent threads
QThread and • Qt support multi-threading and encapsulates threads using QThread class
QtConcurrent •

QObjects are thread safe and re-entrant, communicate across threads
Only have one GUI thread (QApplication)
• Widgets inheritedfrom QWidget not thread safe

• Executing in run() method


• Start event loop calling exec

Thread has:
> Own stack pointer
> instruction (program) counter
> processor registers
> execution state

Access to:
> shared resources (memory, wait conditionsm nutual exclusive data blocks, semaphores

class MyThread: public QThread {


public: void run (); //execute end when return from run()
};

Void MyThread::run(){
QTcpSocket socket;
socket.connectToHost(hostName, portNumber);
exec();
}
WebKit: open source web content rendering and editing engine
Networking Concepts
QT += webkit

Main classes: Viewing webpage:


> QWebElement = access and edit QWebFrame DOM elements QWebView *view = new QWebView();
> QWebFrame = data object represent frame in web page View -> load(QUrl( www.unisa.ac.za
> QWebHistory = history of visited links associated with QWebPage
> QWebHistoryItem = object represent one visited link in QWebHistory
QWebView = widget used to view and edit web documents
> QWebPage = data object represent web page
QWebPage = object to view and edit web document
> QWebSettings = data object holds settings used by QWebFrame or QWebPage
QUrl = interface for workin with URL s
> QWebView = widget visualizes QWebPage
QWebFrame = data object represent frame in web page
QWebElement = class eccess and edit QWebFrame DOM elements
Only Widget in QWebKit is QWebView
QWebPage download web content behind scenes, process content, reflect results user interface

Browsing web using HTTP protocol (hypertext transfer protocol)


Networking Concepts
HTTP built on top of TCP (transmission control protocol) which is built in IP (internet protocol)

http://qt-project.org/products/qt-for-mobile
QUrl class:
ftp://ftp.qt.nokia.com:2021

path

Scheme
Host port
ftp://person:[email protected]:2021
http://qt-project.org/documents#qt-other

userName
fragment password
TCP Sockets UDP Sockets
Guaranteed in-order delivery File and forget QT += network
Point-to-point only Point-to-pint or broadcast

Correct delivery important Time more important than delivery

QTcpSocket = represent a socket


QTcpServer = represent a server, listen incomming onnections generating
QToSocket instances for each connection
Person
Memento
- name: QString
- birthDate: QDate - state: QStringList

- Memento()
+ Person(QString, QDate) - getState)_: QStringList
+ setMemento(Memento) - setState(QStringList)
+ createMemeonto(): Memento

Caretaker

- person: Person
- memento: Memento

You might also like