1. Trang chủ
  2. » Công Nghệ Thông Tin

The book of qt 4 the art of building qt applications - phần 10 pptx

37 376 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 37
Dung lượng 336,32 KB

Nội dung

B Tulip: Containersand Algorithms stack datastructure,however.For this reason it is recommended that you usethe methods provided directlybyQStack. As aJava-style iterator,QVectorIterat or is used;itfunctionswiththe semanticsof theQVector base class. B.3.2Queues(QQueue) In manyapplications you willnot be able to avoidhavingtouse aqueue.The possibilitiesare wideranging—queuesare used to implementbuffers, 5 as temporary memoryfor tree-based algorithms such as breadth-first search,and muchmore. Qt provides theQQueueclass for queues.Thisismerelyaspecializationofthe QList. It is easyto seethe thinking behind this desi gn decision,because aQList performs wellwheninserting anddeleting at thebeginning andend of th elist. To getavalue into thefront of thequeue,the enqueue()method is used.Asa parameter it expectsavalue of thetype that was used as thetype parameter in the declaration of thequeue.dequeue() removes thelastelement from thequeue and returnsit. As aJava-style iterator,the iterator of thebaseclass is used (inthe same wayas QStack),thatis, QListIterator. B.4AssociativeArrays At first glance,the containerclassesQMapand QHashseem to servethe same pur- pose: Theysavealistofkey-value pairs in which accesstothe resultingcollection of valuesisusuallyperformedbyspecifyingnot an index,but akey.Nevertheless, thereare differences between thetwoclasses, both in theirimplementationand in theirperformanceinspecific circumstances. B.4.1Dictionaries(QMap) QMap providesadictionaryandisthe slower of thetwodatastructures, butit also sortsthe key-value pairs automatically.Thisisofparticularrelevance to the programmerifhewants to iterateover thedatastructure:Whenusing QMap iterators, th eoutputisalreadysorted bykey. ThefollowingexampleshowshowaQMapthatassociatesastring to an integer value is created: 5 NottobeconfusedwithQBuffer, which represents an input/outputdevice; seeChapter 11. 404 B.4 Associative Arrays // mapdemo/main.cpp #include <QMap> #include <QMapIterator> #include <QDebug> intmain() { QMap<QString, int>map; map["one"]=1;//insert using the [] operator map["two"]=2; map.insert("seven",7); // insert using insert() qDebug() << map["seven"];//readusing the [] operator qDebug() << map.value("seven"); // readusing value() QMapIterator<QString, int>i(map); while (i.hasNext()) { i.next(); qDebug() << i.key() << ":"<< i.value(); } return0; } With thehelpofthe indexoperatororbyusinginsert(), wefill up thedictionary mapwithvalues. Theargument in brackets or thefirstargument to insert() is the key,for which,inthiscase, weuse valuesofthe QStringtype.Itisworth your while to useinsert()ratherthanthe indexoperator, bytheway:The latter is often significantlyslower wheninserting en tries. Cautionmustbeusedwhenaccessing theQMap, however.The value() method and theindexoperatorbehaveinthe same wayonlywithobjectsdeclaredasconst. Otherwise, theindexoperatorhas asometimesnastyside effect:Ifthe keybeing sought is missing,itcreat es anewemptyentry.Asaresult,aninstanceofQMap can become hugelyinflated,particularlyafter manyad hocqueries havebeen made against it,inwhich thousandsofunsuccessful accessestake place.Accessing the QMap bymeansofvalue() protects it from this side effect. At the endofthe exampleaQMapIterator goes throughthe listentrybyentry.In contrast to theiteratorsintroduce duntil now,thisone hasthe methods key() and value() to do justicetothe nature of thedatastructure. Data typesthatyou definemustfulfillspecial conditions in ordertobeusedas keysindictionaries.Adatatype whose valueswillappear as keysinaQMap must implementthe less-thanoperator(operator<()) to allowthemembers of theQMap to be sorted.Wecarrythis outinthe nextexampleusing adataset classthat provides arecordwithfields for an employee’sfirstand last name: 405 B Tulip: Containersand Algorithms // customvaluedemo/datensatz.h #ifndef DATENSATZ_H #define DATENSATZ_H #include <QString> #include <QHash> class Record { public: Record(const QString &surname, const QString &forename) { m_forename =forename; m_surname =surname; } QString forename() const { returnm_forename; } QString surname() const { returnm_surname; } private: QString m_forename; QString m_surname; } ; Nowweimplement therequiredless-thanoperator: // customvaluedemo/datensatz.h(continued) inline bool operator<(const Record&e1, const Record&e2) { if (e1.surname() != e2.surname() ) returne1.surname() <e2.surname(); returne1.forename() <e2.forename(); } Thefollowingprogram saves some datasets in aQMap, together withanIDthat displaysthe personnelnumber: // customvaluedemo/main.cpp #include "datensatz.h" #include <QHash> #include <QMap> #include <QSet> #include <QDebug> intmain() { Recordd1("Molkentin","Daniel"); Recordd2("Molkentin","Moritz"); 406 B.4 Associative Arrays Recordd3("Molkentin","Philipp"); QMap<int,Record> map; map.insert(0,d1); map.insert(1, d2); map.insert(2,d3); QMapIterator<int,Record> mi(map); while (mi.hasNext() ) { mi.next(); qDebug() << mi.key() << ":" << mi.value().surname() << mi.value().forename(); } We requirethe QHashheaderfile for theextensionsonpage 410,where wewill make ourclass compatible withhashes. Requirements of KeyElements As wehavejustseen,because aQMapkeepsits entriessorted according to key value,the classthatisusedasthe keytype musthavealess-thanoperator(here, <),sothatthe containercan setupanorderingofits elements.Ifyou tryto define aQMapusing aclass without such an operatorfor thekeytype parameter,the compilercomplains that theless-thanoperatorisnot defined. B.4.2Allowing SeveralIdentical Keys ( QMultiMap) QMap hasafurtherlimitationthatmaybe adisadvantage in some situations:It doesnot allowdistinct entriesinacontainertohavekeyswiththe same value. (Thus,the sequence of keyvaluesinthe sorted containerisstrictlymonotone.) If asecondcalltoinsert()ismade usinganalreadyexisting keyvalue,the datavalue currentlyassociatedwiththe keyvalue is overwritten withthe newdat avalue. Butwhathappensinthe followingscenario? Asawmill receives dailydeliveriesof different tree trunks. Aworkeristaskedtorecordthe number of trunksand the type of wood. However,itisimportant for theoperatortosaveindividualdeliveries as separatedat asets for later statistical evaluation.AQMap is inadequatehere, because it couldonlyrepresentthe most rece nt deliveriesofeach type of wood. 6 Trolltechprovides theQMultiMap classfor this.Thisvariesconsiderablyfrom QMap in anumber of respects.AQMultiMapcan contain several datasets allhavingthe same keyvalue.Also, QMultiMapdispenses withthe indexoperatorfor technical 6 Admittedly,inrealitysuch aproblemwould probablybe so lved withanSQL database.Ifyou are interestedindatabaseaccess,werefer you to Chapter9,where thesubject of SQLdatabases is treated in more detail. 407 B Tulip: Containersand Algorithms reasons. Also,value() andreplace() operate on theelement that was last inserted into theQMultiMap instance. To read outall datasets covered byaspecific key,values()isthe method of choice. When given aspecific keyvalue as aparameter,itreturnsaQListofall values associatedwiththatkey. Thefollowingcode implements thesawmill examplewiththe help of aQMultiMap. Each insert() instructioninserts anewelementwithout overwriting apossiblyex- isting key.The integer listbeech, which is created usingvalues(), contains allthe incoming beechtrunksstartingwiththe value last inserted: // multimapdemo/main.cpp #include <QMap> #include <QDebug> intmain() { QMultiMap<QString, int>trunks; trunks.insert("Beech",100); trunks.insert("Umbrellapine",50); trunks.insert("Maple",50); trunks.insert("Beech",20); trunks.insert("Fir",70); trunks.insert("Beech",40); QList<int>beeches=trunk.values("Beech"); qDebug() << beeches; // output:40,20,100 return0; } QMultiMapalsoprovides theaddition operators +and +=, which can be used to combineseveral associativetablesintoone single one. Forour examplethismeans that wecan verysimplysummarizethe incoming goods from several differentmills bysumming thecorresponding QMultiMaps.Inthiscaseitmayalso be worthwhile to make atype definitionfor thespecializationofQMultiMap that is in use: typedefQMultiMap<QString, int>TrunkCountMultiMap; TrunkCountMultiMapmill1result=mill1.incoming(); TrunkCountMultiMapmill2result=mill2.incoming(); TrunkCountMultiMapmill3result=mill3.incoming(); TrunkCountMultiMaptotal=mill1result+mill2result+mill3result; We assume here that thealreadydefined objectsmill1,mill2,and mill3 havea incoming() method, which returnsaTrunkCountMultiMap. Afterthe code executes, thetotal QMultiMapcontainsthe combined goods from allfactories. 408 B.4 Associative Arrays B.4.3HashTableswith QHash Thedatastructure QHashisverysimilartothe QMap in howit functions. However, whereas aQMapsorts itsentries bykeyvalue,QHash uses ahashtable internally to storeits entries. This meansthataQHashisunsorted.Compensatingfor this ,it is slightlyfaster than QMap whensearching for entrieswithspecifiedkeys. TheAPIs of thetwodatastructuresare almost identical,and so wecan rewrite the QMap examplefrompage 404touse QHashinsteadjustbymaking some simple substitutionsinthe code: // hashdemo/main.cpp #include <QHash> #include <QHashIterator> #include <QDebug> intmain() { QHash<QString, int>hash; hash["one"]=1;//insert using [] operator hash["two"]=2; hash.insert("seven",7); // insert using insert() qDebug() << hash["seven"];//valueusing [] operator qDebug() << hash.value("seven"); // valueusing value() QHashIterator<QString, int>i(hash); while (i.hasNext()) { i.next(); qDebug() << i.key() << ":"<< i.value(); } return0; } As withQMap, theindexoperatorinQHash is dangerous,since it insertsanew entryinto thecontainer if thekeyvalue is notfound.Aremedyis againprovided bythevalue() method. This generates an emptyentryif thevalue is missing in the hash,but it onlyreturnsit, anddoesnot insert it into thehash. Things become interesting whenyou startcreatingyourowncla ssestouse as keys. Such classesmustimplement an equalitycomparison operator(operator==()) as wellasahelper function bythenameofqHash() that implements thehash function. Let’sre-implementthe exampleprogram from page 406. Theindexoperatoris quicklyimplemented:Itcompares thefirstand last name stringsofbothdatasets, andreturnstrueiftheyareequal;otherwise, it returnsfalse. Calculatingagood hash value is muchmoredifficult, because this number must 409 B Tulip: Containersand Algorithms distinguishthe elementasmuchaspossible from otherelementsinaQHashin- stance.Too manyelements withthe same hash value result in performancepenal- ties.Since theqHash() helper method is implemented for primitivedatatypesand thosespecifiedbyQt, wecan make useofthe specifichashfunction of theQString classtocalculate ahashvalue for first andlastnames (insteadofdoing thecalcu- lation entirelyfrom scratch). Combiningthe resultsusing an exclusiveor(^) in turn generates on euniquehashvalue for theentirerecordfromthe hash valuesfor the twoparts of therecord: // customvaluedemo/datensatz.h(continued) inline bool operator==(const Record&e1, const Record&e2) { return(e1.surname() == e2.surname()) && (e1.forename() == e2.forename()); } inline uintqHash(const Record&key) { returnqHash(key.surname()) ˆqHash(key.forename()); } #endif // DATASET_H Nowwecan useour datastructure withQHash in exactlythesamewayas wedid withQMap. Fordemonstration purposes,the exampleherealsodisplaysthe hash value for each entryin thehash: // customvaluedemo/main.cpp (continued) QHash<int,Record> hash; hash.insert(0,d1); hash.insert(1, d2); hash.insert(2,d3); QHashIterator<int,Record> hi(hash); while (hi.hasNext() ) { hi.next(); qDebug() << hi.key() << ":" << hi.value().surname() << hi.value().forename(); qDebug() << qHash(hi.value()); } Just likeQMap, QHashalsohas asubclassthatallowsdistinctentries withide ntical keystoberecorded. It is calledQMultiHash, an ditchanges thebehaviorofinsert() so that it no longer overwrites an alreadyexisting entrywithaspecified key,and it also reimplements replace()sothatitreplacesthe most recentlyinserted entryif several entriesinthe hash table havethe same key. 410 B.4 Associative Arrays Like QMultiMap, QMultiHash also allowsyou to combineseveral QMultiHashes into onehashwiththe +operator. B.4.4Hash-basedAmountswith QSet If whatyou need is notanassociativearray,but just asimplelistthatdoesnot havetobesorted andisveryfasttosearch, then QSet maybe thebestchoice. QSet is implemented internallyas aQHash,but it provides manyof thesemantics of QString, such as cyclingthrough allelementswithforeach(). We can illustrate this usingour dataset example, in which wefirstinsertsome previouslygenerated entriesintoacustomized QSet. To do this weuse the<< operator. We cyclethrough thelistitselfwithforeach(): // customvaluedemo/main.cpp (continued) QSet<Record> set; set<< d1 << d2<< d3; foreach(Recordd,set) qDebug() << d.surname() << ":"<< d.forename(); return0; } In addition,QSetprovides allthe basicoperationsfor sets knownfrommathemat- ics, such as setunion andset difference. Thefollowingexamplefirstcreat es two sets andthenforms theset differenceofone of thetwosets in terms of theother one. Thesubtract () method responsible for this operates direct lyon theset object that receives thecall, which in this caseisset1.Itremoves from this setall the elements that also existinthe setpassedtoitasanargument,hereset2: // setdemo/main.cpp #include <QSet> #include <QDebug> intmain() { QSet<int>set1; set1<<1<< 2<< 3<< 4<<5<< 6; QSet<int>set2; set2 << 4<<5<< 6<< 7<< 8<<9; set1.subtract(set2); // output:1,2,3 qDebug() << "set1remainders:"<< set1; 411 B Tulip: Containersand Algorithms return0; } In th esamewaythereare themethods unite(), for theunion,and intersect(), for making intersections.These also change theQSetinstancewithwhich theyare called. B.5Algorithms B.5.1The foreach Keyword As an alternativetoconst iterators, thereisthe foreach() macro: // stringlistdemo/main.cpp #include <QStringList> #include <QDebug> intmain() { QStringList names; names<< "Patricia"<< "Markus" << "Uli"; foreach(QString name, names) qDebug() << name; return0; } Thosewho do notliketotaint theC++ namespace (C++ inven torStroustrupis working on anativeforeach keywordinthe coming language versions) can instead usethe synonymQ_FOREACH(). Themacroisslightlyslower than aconst iterator, butthisisonlynoticeable withverylargedatastructures. In addition Q_FOREACHsupports allthe validationcharacteristics for variable dec- larationsthatfor() also has. This meansthatavariable declared in theloop header is no longer valid outsidethe loop for ISO-compatible compilers. It is important to bear in mind that foreach() creates acopyof thedatastructure. In theloop shownhere, anymodification of thelistthereforehas no effect on theoriginallist. If you areworried that Qt make sacomplete copyof thelist, you needn’tbe: Even withlists,Qtmakesuse of implicit sharing(seepage 40). Thefact that foreach() creates copies of thedatastructure haseven more positive aspects: foreach(QString results,results()) 412 B.5 Algorithms If results()containsanoperation withcost k beforereturningthe datastructure andthe function returnsacontainerwith i en tries, atotal cost would arise, with anormalfor loop of k ∗ i .The copyensuresthatthere is acachingeffect ,which brings downthe cost for k to aexpenditureof k + i withcosts of O (1) for k , because results()isonlycalledonce. B.5.2Sorting Tulip also contains functionsfor sortingdatainsidecontainers. Themostfrequently used of theseiscalledqSort() andexpectsacontainerasanargument,which it sortswiththe heap sort algorithm. // listdemo/main.cpp #include <QList> #include <QDebug> intmain() { QList<int>values; values<< 1<<10<< 5<<6<< 7<< 3; qSort(values); qDebug() << values; // output:(1, 3,5,6,7,10) return0; } This is also veryefficient withlarge amountsofdata, as it works in linear-logarithmic time ( O ( n log n ) ). Duringthe stepsofthe sortingprocess,the qSort()function makesuse of theC++ comparison operatoroperator<() to determine whether twoelementsshouldbe swapped.Iftwoobjectsare equalfor thepurposeofcomparison, it is left up to the implementation of qSort()whether theyareswapped or not. If operator<() does notcompareall object properties, theresultmayvarysubtly. Forthisreasonthere is an additionalfunction qStableSort(), which is also imple- mented bymeansofthe heap sort algorithm. In contrast to qSort(), however,it ensuresthatelementsthatare “equal”toone anotheralwaysremainintheir orig- inal sequence in thefinal, sorted list. Bothfunctionsalsohaveanoverloadedvariation:Insteadofacomplete container, theyalternativelyexpect twoiterators, thefirstofwhich pointstothe first element to be sorted andthe second to theelement after thelastobject to be sorted. This variant can acceptafunction pointer that references afunction implementing acomparisonoperation otherthanoperator<() to be used during thesort. This comparison function mustaccept andcomparetwoparametersofthe same type: // sortdemo/main.cpp 413 [...]... QTcpSocket 40 , 318, 333, 3 34, 340 QtDBus 43 , 47 QtDebug 387 QTemporaryFile 318 QTestLib 43 , 46 QTextBrowser 349 , 361 QTextCodec 1 14 QTextDocument 123 redo 117 undo 117 QTextEdit 106 , 115, 142 open new document 116 preventing line wrap 106 setDocument() 116 setting font type 106 size policy 144 text format 1 14 undo see QTextDocument QtGlobal 386 QtGui 42 , 44 45 QThread see threads QThreadStorage 345 – 347 QTime... 43 Qt 4. 2 43 Qt Assistant see Assistant Qt Designer see Designer Qt Linguist see Linguist Qt Solutions 47 Qt- 3 classes 46 Qt3 Support 43 , 46 QT FATAL WARNINGS (environment variable) 388 QT NO DEBUG OUTPUT (environment variable) 386 QT NO WARNING OUTPUT (environment variable) 388 QT TR NOOP (macro) 381 QTableView 211 QTableWidget 251, 253 QtCore 42 , 44 , 332 debug variations 28 QTcpServer 333, 338 QTcpSocket... AccessibleTextRole in Interview 209 action see QAction Action Editor of the Designer 108 Active-X components 47 ActiveQt 47 addition operator QMultiHash 41 1 QMultiMap 40 8 addStretch() 148 addWidget() 30, 32, 34, 144 , 145 in QGridLayout 148 with splitters 150 with stacked layouts 157 algorithms 41 2 42 2 binary search 41 6 41 8 copy 41 5 41 6 heap sort 41 3 search 41 4 41 8 sort see sorting aligning DisplayRole data 209 on... QFileDialog 113, 175–178 flags 175 qFill() 42 0 qFind() 41 4 QFont 182 QFontDialog 182–183 QFontMetrics 288 QFrame 41 , 42 QFtp 333 QGridLayout 33– 34, 148 – 149 , 303, 362 addWidget() 34 column numbers 34 coordinate system 34 with Designer 84 line numbers 34 in the Qt inheritance hierarchy 42 QHash 283, 40 9 41 1 qHash() 40 9 QHBoxLayout 33 in Designer 84 in the Qt inheritance hierarchy 42 QHeaderView 211 QHostAddress... threads QThreadStorage 345 – 347 QTime 188 QTimer 3 34, 350 singleshot timer 3 04 QTimerEvent 188, 189 QtNetwork 42 , 45 , 332 QtOpenGL 42 , 45 QTranslator 378, 379 QTreeView 210 QTreeWidget 251, 252 QtSql 43 , 45 , 257–270 displaying database errors 261 establishing connection 260 making queries 261 model for Interview 265–270 temporary database 265 QtSvg 43 , 46 QtXml 43 , 45 , 353–373 QUdpSocket 318, 333 question... (value range: −2 147 48 3 648 to +2 147 48 3 647 ) 8 42 2 Write Portable Code by Brian Hook (No Starch Press, 2005) B.6 Qt- specific Type Definitions qint 64 values are 6 4- bit values (value range: −232 to +232 − 1) To generate such large values as literals, the Q_INT 64_ C() macro exists, since a number of compilers do not support 6 4- bit literals directly: qint 64 value = Q INT 64 C(93283 845 745 945 9); qlonglong... the Qt inheritance hierarchy 42 QStringList 395 comparing with QVector 41 9 QStringListModel 212, 221 QStyle 330 QSvgRenderer 301 QSvgWidget 301 qSwap() 42 0 Qt contents of individual libraries 42 German translation sources 380 information box about 173 installing 23 open source edition for Windows 24 size 42 source code 23 QT (qmake variable) 43 , 257, 301, 43 6 332, 3 54 Qt 4. 0 42 Qt 4. 1 43 Qt. .. connections 347 , 348 queues see QQueue quint16 42 3 quint32 42 3 quint 64 423 quint8 42 3 quit() 26, 36, 112 qulonglong 42 3 qUpperBound() 41 7 41 8 QUrl 195, 3 64 converting to file path 200 QValidator 70 QVariant 135, 200 converting into native data types 138 converting to a string 366 QVBoxLayout 30, 144 – 145 addWidget() see addWidget() creating in Designer 84 in the Qt inheritance hierarchy 42 QVector 40 1 40 2 filling... parameters: two STL iterators, one of which marks the beginning of the area in the first data structure containing the elements to be compared, and the other, which marks the end of this area The third parameter is an iterator on the second data structure and points to the element from which the comparison (which comes to a stop at the end of the container) should start The following program accordingly... manipulation 46 , 301 dotted lines 295 double 42 3 double buffering 282 switch off 283 drag and drop 1 94 201, 323 bug in Qt 4. 1.2 245 of images 1 94 implementing in models 241 – 245 drawing with Qt 271–317 re- ˜ a widget 296 re-˜ the screen 280 on widgets 280–283 drawing path see Painter paths drop actions types 244 DTD handling in SAX see QXmlDTDHandler dynamic text generating 1 24 dynamic cast 248 E ECMA . iterators, oneofwhich marksthe beginning of theareainthe first datastructure containing theelementstobecompared,and theother,which marksthe endofthisarea. Thethird parameter is an iterator on theseconddatastructu. integersuse 32 bits(value range: − 2 147 48 3 648 to +2 147 483 647 ). 8 WritePortableCode byBrianHook (NoStarchPress,2005). 42 2 B.6 Qt -specificTypeDefinitions qint 64 valuesare 6 4- bit values(value range: −. literalsdirectly: quint64value=Q UINT 64 C(93283 845 745 945 9); Similartoqlonglong,qulonglongisasynonymfor quint 64. B.6.2Floating-point Values With qreal, Qt defines afloating-point number of double precision. This corre- sponds

Ngày đăng: 13/08/2014, 08:21

TỪ KHÓA LIÊN QUAN