Presentation is loading. Please wait.

Presentation is loading. Please wait.

Strings, containers, I/O

Similar presentations

Presentation on theme: "Strings, containers, I/O"— Presentation transcript:

1 Strings, containers, I/O
Maciej Dębiński

2 Strings, containers, I/O
Module Overview This module covers a wide range of APIs useful to application developers - container classes, string handling, timers, files and streams, among others. Course Duration 3~4 hours. Target Audience Anyone. Prerequisites Basic knowledge of C++ programming. Basic knowledge of Qt’s painting mechanism. Training method Class room or self study. MODULE CONTENT 1. Qt container classes 2. String classes and localization in Qt 3. QUrl 4. Regular expressions in Qt 5. Basic input validation in Qt 6. Timers 7. Brief overview of printing in Qt 8. Access to files & directories in Qt 9. Binary and text-oriented streams in Qt 2

3 Containers in Qt

4 Characteristics of Qt containers
The Qt library provides a set of general purpose template-based container classes: QList, QVector, QMap, … Qt containers have been designed to be lighter, safer, and easier to use than the STL containers. According to the documentation, Qt containers have been optimized for speed, low memory footprint(脚印) and minimal code expansion. All container classes by use the concept of implicit sharing to minimize copying overhead. All methods of Qt container classes are reentrant(折返).

5 Sequential containers
Qt provides the following sequential containers: QList - an array-based general-purpose list QLinkedList - a linked-list implementation of the list QVector - array of values occupying contiguous(连续的) memory QStack - a LIFO convenience subclass of QVector QQueue - a FIFO convenience subclass of QList QList internally stores pointers to objects passed to it in a contiguous array with pre-allocation of a few elements in the beginning and end to speed up insertion. QVector stores the objects inserted into it themselves in a contiguous region of memory.

6 Associative containers
Qt provides the following associative containers: QMap - an associative array which maps keys to values QHash - a hash-table-based dictionary QSet - a representation of a mathematical set QMultiMap - a convenience subclass of QMap, which can hold multiple values associated with each key QMultiHash - a convenience subclass of QHash, which can hold multiple values associated with each key QMap stores values in Key order. QMap is implemented as a skip-list-based dictionary.

7 Type requirements Objects must fulfill certain requirements in order to be able to be stored in Qt containers (and STL as well, for that matter). They must be an assignable data type, i.e. it must provide a default constructor, a copy constructor, an assignment operator.(operator=) Keys in QMap and QMultiMap must provide operator<() (so that QMap can determine the order of keys) Keys in QHash, QMultiHash and QSet must provide operator==() and global qHash(Key) function.

8 Type requirements QObject and all QObject subclasses (including QWidget) do not fullfill the first requirement. Rather than storing the objects directly, store pointers instead. QVector<QWidget> vec; // WRONG QVector<QWidget*> vec; // OK Some functions in the containers have additional requirements towards the inserted elements, e.g.: operator==() needs to be provided by the value type, if QMap or QHash’s == or != operators are used. operator==() needs to be provided by the value type, if indexOf() or lastIndexOf() method of QList or QVector are used. operator>>() and operator<<() need to be provided for both key type and value type, if respective container’s << or >> operator is used.

9 Adding elements to containers
In case of sequential containers(顺序容器), the easiest way to add new elements is to use the << operator. QList<QString> list; list << ”Apple" << ”Orange" << ”Kiwi” << ”Banana”; QVector<double> numbers; numbers << 0.0 << 0.5 << 1.0; The following methods are also available: void append ( const T & value ); void prepend ( const T & value ); void insert ( int i, const T & value );); // not available in QLinkedList iterator insert ( iterator before, const T & value ); void push_back ( const T & value ); void push_front ( const T & value );

10 Adding elements to containers
In associative containers(关联容器), key-value pairs are stored, so << operator is not available. Instead, [] operator is used. QMap<int, QString> map; map[1] = "one"; map[2] = “two”; map[3] = "three"; QHash<QString, double> hash; hash[“Bob”] = 13.5; hash[“John”] = 15.0; hash[“Bob”] = 10.5; The following methods are also available: iterator insert ( const Key & key, const T & value ); iterator insertMulti ( const Key & key, const T & value ); QMap<int, int> map; map.insert(10, 1); // map contains pair map.insert(10, 5); // map contains pair exists, but not map.insertMulti(10, 6); // map contains both pairs and

11 Access to items in containers
Elements stored in sequential containers can be accessed in a number of ways: First or last element By index Using Java-style iterators Using STL-style iterators Elements stored in associative containers are accessed: By key By value

12 Random access The following methods for accessing previously stored values are available in sequential containers: const T & at ( int i ) const; T value ( int i ) const; T & operator[] ( int i ); T takeAt ( int i ); T & front (); T & back (); T & first (); T & last (); T takeFirst (); T takeLast (); Access by index is not available in QLinkedList

13 Access by key/value Access to key-value pairs in associative containers is somewhat more concise than in sequential containers: const T value ( const Key & key ) const; const Key key ( const T & value ) const; T & operator[] ( const Key & key ); QList<T> values () const; QList<Key> keys () const; Methods value() and key() return a default-constructed value if the looked-up parameter was not found in the container. Operator [] inserts a new pair <key - default-constructed value> if there was no value assigned to the key yet. Then it returns a reference to that default-constructed value.

14 Iterators in Qt Qt provides two types of iterators:
STL-style iterators Java-style iterators The differences between these two types are summarized below: Different class names (QListIterator<T> vs. QList<T>::const_iterator) Different APIs STL-style iterators point directly to individual elements of the container, while Java-style iterators point between the elements. Java-style STL-style

15 Java-style iterators The following Java-style iterators are available in Qt: Read-only: QListIterator, QLinkedListIterator, QVectorIterator, QSetIterator, QMapIterator, QHashIterator Read-write: QMutableListIterator, QMutableLinkedListIterator, QMutable-VectorIterator, QMutableSetIterator, QMutableMapIterator, QMutableHash-Iterator Whenever possible, use the read-only versions as they are more efficient. With read-write iterators, there is also risk of causing a detachment(分离) of implicitly shared data (i.e. making data’s deep copy), which is an unnecessary overhead.

16 Java-style iterators The read-only iterators’ API:
bool findNext( const T & value ); bool findPrevious( const T & value ); bool hasNext() const; bool hasPrevious() const; const T & next(); const T & previous(); const T & peekNext() const; const T & peekPrevious() const; void toBack(); void toFront(); The read-write iterators implement in addition: void insert ( const T & value ); void remove (); void setValue ( const T & value ) const; T & value (); Also, obviously, next() and previous() families of methods return non-const references to stored elements. Use key() and value() methods with iterators of associative containers.

17 Java-style iterators QList<QString> names; names << “Bob" << “John" << “Patrick" << “Sue"; QListIterator<QString> i(names); while ( i.hasNext() ) qDebug() <<; i.toBack(); while (i.hasPrevious()) qDebug() << i.previous(); QMutableListIterator<QString> i(names); while ( i.hasNext() ) { if ( % 2 != 0 ) i.remove(); } QMap<QString, QString> map; map.insert("Guatemala City", "Guatemala"); map.insert("Mexico City", "Mexico"); map.insert("Moscow", "Russia"); QMutableMapIterator<QString,QString> i(map); while (i.hasNext()) { if ("City")) i.remove(); } QMap<int, QWidget *> map; QHash<int, QWidget *> hash; QMapIterator<int, QWidget *> i(map);; hash.insert(i.key(), i.value());

18 STL-style iterators The following STL-style iterators are available in Qt: Read-write QList<T>::iterator QLinkedList<T>::iterator QVector<T>::iterator QSet<T>::iterator QMap<T>::iterator QHash<T>::iterator The following STL-style iterators are available in Qt: Read-only QList<T>::const_iterator QLinkedList<T>::const_iterator QVector<T>::const_iterator QSet<T>::const_iterator QMap<T>::const_iterator QHash<T>::const_iterator With STL-style iterators, ++ is used to move iterator forward, -- to move it backward, and * (dereference operator) is used for retrieving the value of the element.

19 STL-style iterators Qt containers provide the following functions used in conjunction with STL-style iterators: iterator begin (); const_iterator constBegin () const; iterator end (); const_iterator constEnd () const; iterator insert ( iterator before, const T & value ); QList<QString>::const_iterator i; for (i = list.constBegin(); i != list.constEnd(); ++i) qDebug() << *i;

20 Foreach keyword To make iterating over the contents of containers easier, Qt provides a new keyword ‘foreach’. Under the hood(引擎盖), ‘foreach’ is a macro. The syntax is as follows: foreach (variable, container) statement Unless the data type contains a comma, variable can be declared inside of the parenthesis itself. Qt automatically takes a copy of the container when it enters a foreach loop. However, since all Qt containers use implicit sharing, the copy is very quick and does not involve copying all stored elements. Original container will remain unchanged, even if you modify the container as you are iterating.

21 Foreach keyword - examples
QLinkedList<QString> list; list << “one” << “two” << “three” << QString() << “four”; foreach (const QString& str, list) { if (str.isEmpty()) break; qDebug() << str; } QString str; foreach (str, list) { QMap<QString, int> map; map.insert(“one”, 1); foreach (const QString &str, map.keys()) { qDebug() << str << ":" << map.value(str);

22 QStack & QQueue QStack & QQueue are convenience classes based on QVector & QList respectively, which provide last-in-first-out (LIFO) and first-in-first-out (FIFO) semantics(语义). QStack adds the following methods to QVector API: T pop (); void push ( const T & t ); T & top (); QQueue introduces the following methods to QList API: T dequeue (); void enqueue ( const T & t ); T & head ();

23 Container growth strategies
To avoid reallocation of elements every time containers grow, Qt usually allocates more memory that necessary in advance and performs a reallocation only when that memory runs out. For example: QHash and QSet grows by power of 2 every time QList and QString grow as follows: Grows 8 bytes at a time until it reaches size 40 bytes From 40 to 8168 it grow to the next power of 2 minus 24 bytes Above it grows by 4096 bytes Some containers, e.g. QVector & QHash, provide methods to manually preallocate a number of elements: void reserve ( int size ); void squeeze (); int capacity () const;

24 Algorithms Similarly to STL, Qt comes bundled with a set of algorithms, which can be used to perform certain frequent operations on containers and sets of their elements. qDeleteAll() - deletes a range of elements from a container qBinaryFind() - finds an element in a container using binary search qFind() - finds an element in a container qSwap() - exchanges two values qSort() - sorts a set of values qStableSort() - sorts a set of items without changing the order of equal items qFill() - fills a range of elements with particular values qCopy() - copies a range of elements from one container to another qCount() - returns the number of occurrences of an element in a range of elements

25 Algorithms Different algorithms can have different requirements for the iterators they accept. For example, qSort(), qBinarySearch() and qStableSort() require two random access iterators - iterators which can be used to jump to any element in any direction. Only QList and QVector’s modifiable iterators fulfill all requirements of random access iterators (because their elements are stored in a contiguous memory region). Other algorithms have less strict requirements and can be used with all modifiable/non-modifiable STL-style iterators.

26 Algorithms - examples QVector<int> vector; vect << 3 << 10 << 4 << 6 << 12 << 8; qSort( vector.begin(), vector.end() ); // 3,4,6,8,10,12 QVector<int>::iterator i = qBinaryFind( vector.begin(), vector.end(), 12 ); bool isLastItem = (i == vector.end()-1); // isLastItem == true qFill( vector.begin(), vector.begin()+2, 5 ); // 5,5,5,8,10,12 int count; qCount( vector.begin(), vector.end(), 5, count ); // count = 3 QList<int> list; list << 5 << 5 << 5 << 8 << 10; bool isEqual = qEqual( vector.begin(), vector.end(), list.begin() ); // isEqual == false list << 12; isEqual = qEqual( vector.begin(), vector.end(), list.begin() ); // isEqual == true

27 More information For those, who need more detailed information on each of the containers provided by Qt, here are some references:

28 Strings in Qt

29 Qstring QString is the basic Qt class for handling Unicode strings.
Every character within QString is represented by a 16-bit Unicode 4.0 (5.1?) QChar character. Behind the scenes, QString uses implicit sharing (copy-on-write) to reduce memory usage and to avoid the needless copying of data. Traditional 8-bit ‘\0’-terminated strings and arrays of raw 8-bit data are represented in Qt by QByteArray class. QString class provides a large number of overloaded methods meant to make using it with traditional string literals and character arrays as easy and intuitive as possible. QString str = "Hello";

30 QString API - string manipulation
QString contains a large number of methods for performing all sorts of basic string manipulation, concatenation and searching: QString & append ( const QString & str ); QString & insert ( int position, const QString & str ); QString & prepend ( const QString & str ); QString & replace ( int position, int n, const QString & after ); QString right ( int n ) const; QString left ( int n ) const; QString mid ( int position, int n = -1 ) const; QString toUpper () const; QString toLower () const; int indexOf ( const QString & str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive ) const; int lastIndexOf ( const QString & str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive ) const;

31 QString API - number-string conversion(Switch)
QString provides a number of methods for converting between numbers and strings. Here are only a few examples: float toFloat ( bool * ok = 0 ) const; int toInt ( bool * ok = 0, int base = 10 ) const; long toLong ( bool * ok = 0, int base = 10 ) const; short toShort ( bool * ok = 0, int base = 10 ) const; QString & setNum ( int n, int base = 10 ); QString & setNum ( long n, int base = 10 ); QString & setNum ( short n, int base = 10 ); QString & setNum ( double n, char format = 'g', int precision = 6 );

32 QString API - number-string conversion
There are also a few static functions, which produce a string representation of a given number: QString number ( long n, int base = 10 ); QString number ( double n, char format = 'g', int precision = 6 ); QString number ( ulong n, int base = 10 ); QString number ( int n, int base = 10 ); long n = 127; bool ok; QString str = QString::number(n, 16); // str == 7f int value = str.toInt(&ok); // value = 0; ok == false J:Means convert failed value = str.toInt(&ok, 16); // value = 127; ok == true J:means convert succeed. str.setNum(50505); // str == “50505“

33 QString API - arguments
QString provides a family of printf-like functions for easy substitution of numbers and strings into another string: QString arg ( const QString & a, int fieldWidth = 0, const QChar & fillChar = QLatin1Char( ' ' ) ) const; QString arg ( int a, int fieldWidth = 0, int base = 10, const QChar & fillChar = QLatin1Char( ' ' ) ) const; QString str = QString(“File no %1”).arg(100); // str == “File no 100” str = QString(“Could not load file %1 from %2 - error code: %3”) .arg(“myfile.doc”).arg(“\home\papa\”).arg(3); str = QString(“%1 is %2 in hexadecimal notation”).arg(255).arg(255,0,16); QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); str = QString("%L1") .arg(12345); // str == 12,345

34 String conversions While QString stores its character data in Unicode format, it is also possible to convert it to various 8-bit encodings should it be necessary. QString provides the following methods for this: toAscii() uses the coded returned by QTextCodec::codecForCStrings() toLatin1() toUtf8() toLocal8Bit() - uses system’s local encoding Similar methods for reverse convertion ( fromXXX() ) also exist. By default, C strings are converted to Unicode using toAscii() if no explicit conversion is requested.

35 String conversions Encodings to be used when applying default conversion can be changed by using QTextCodec::setCodecForCStrings() static method. On systems which use other encodings than Latin-1, there is a risk that implicit conversion will use an incorrect encoding if appropriate one is not set. To minimize the risk, one can turn implicit conversion off using one or both of the following macros: QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII If the first above macro has been defined, the following line will fail: QString s = “Hello world”; // implicit conversion - compilation error QString s = QString::fromLatin1(“Hello world”); // explicit conversion works

36 Other string classes in Qt
To facilitate working with Latin-1 encoded 8-bit strings Qt provides QLatin1Char and QLatin1String classes. These classes are very thin wrappers around char and char* respectively, and sometimes allow optimizing the source code to avoid constructing temporary QString objects. QString str = …; if (str == "papa" || str == "mama") { ... } // works only if implicit conversion is on if (str == QLatin1String("papa") || str == QLatin1String("mama")) { … } QStringRef class allows to eliminate unnecessary copying of character data when handling substrings of already existing QStrings. QString hello("hello"); QStringRef ref(&hello, 1, 3); // ref points to “ell” in “hello” QStringRef provides read-only API. It is somewhat similar to TPtrC in Symbian.

37 String translation - tr()
In Qt, static method tr() from QObject class is used for translating strings: QString QObject::tr ( const char * sourceText, const char * disambiguation = 0, int n = -1 ); Its parameters are: Text to be translated A comment/hint for the translator to help him distinguish words with multiple meanings If plurals(复数)are used in the sentence, number makes it clear what the value is Examples: QLabel* senderLabel = new QLabel(tr("Name:")); QString message( tr(“Hello dear user!”) ); QPushButton* button = new QPushButton( tr(“&Open”, ”open new window”) ); int n = messages.count(); showMessage(tr("%n message(s) saved", "", n));

38 String translation(ToHere)
tr() function looks up the string passed to it (i.e. the plain not translated version) in the translation files currently installed in the application using QTranslator. Then, it returns the translated version of the string. Translations in Qt are indexed by so-called translation context. Translation context for a QObject subclass is defined inside of the Q_OBJECT macro. If Q_OBJECT macro is not defined, context from the base class will be used. For translation to work, one or more QTranslator objects must be installed in the application at the time this method is called.

39 String translation - QTranslator
In order to install translations from particular file: Load the file using QTranslator::load() Install the translator using QCoreApplication::installTranslator() Many translations can be loaded simultaneously. int main(int argc, char *argv[]) { QApplication app(argc, argv); QTranslator qtTranslator; qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); app.installTranslator(&qtTranslator); QTranslator myappTranslator; myappTranslator.load("myapp_" + QLocale::system().name()); app.installTranslator(&myappTranslator); ... return app.exec(); } Loading Qt translations Loading app-specific translations

40 String translation Installing a new QTranslator or removing one of the previously installed ones (using QCoreApplication::removeTranslator()) generates a QEvent::LanguageChange event propagated to all top-level windows. QTranslators are searched in reverse order and look-up ends as soon as first matching translation is found. You may have noticed that QObject::tr() takes char* as a parameter, but returns QString. The conversion between 8-bit and Unicode 16-bit encoding is done using the codec returned by QTextCodec::codecForTr(); Codec may be changed to a different one using void QTextCodec::setCodecForTr ( QTextCodec * c );

41 String translation Tr() function is only available directly in methods of QObject subclasses, because it is implemented in QObject. If there is a need to mark a string in a global function for translation, one can: Use fully qualified name: e.g. QObject::tr() Use QApplication’s translate() method QString str = QString( qApp->translate(“SomeContext”, “Translated string”) ); If there is a need to translate a string completely outside of a function, e.g. in a global string array, one can use one of these macros: QT_TR_NOOP( “text for translation” ) QT_TRANSLATE_NOOP( “context”, “text for translation” )

42 String translation By declaring the following macro at the very beginning of a class which does not inherit from QObject, developer can add translation facilities to it: Q_DECLARE_TR_FUNCTIONS(ClassName) This macro adds tr() and trUtf8() methods that can be used to translate strings in the class. class MyContainer { Q_DECLARE_TR_FUNCTIONS(MyContainer) public: MyContainer() { QString str = tr( “Hello to my container” ); } ~MyContainer();

43 String translation - other steps
After all strings have been marked with tr() or QT_TR*_NOOP macros and QTranslator object has been installed, you should also make sure that the following steps were performed: All translation files are included in .pro file in the TRANSLATIONS section lupdate utility has been used to generate .ts files for each language Strings in .ts files have been translated to appropriate languages, e.g. in Qt Linguist lrelease utility has been used to compile .ts files to .qm format used by QTranslator

44 Additional information
Further information on QString API is available in its class reference: A few more details about character encodings can be found here: Information about application internationalization are available here:

45 URLs and regular expressions

46 QUrl class A uniform resource locator (URL) is represented in Qt by QUrl class. QUrl implements the following functionality: Constructing and parsing URLs in both encoded and unencoded form Support for internationalized domain names (IDNs) QUrl conforms to URI syntax specification from RFC 3986, scheme extensions from RFC 1738 and folding rules from RFC 3491. According to that specification, an URL consists of several parts: Scheme Authority Path Fragment Query strings

47 URL parts Scheme - ftp User - mike Password - pass User info - mike:pass Host - Port Authority - Path - /cgi-bin/ Query string - color=green

48 QUrl API QUrl provides methods for retrieving and setting the value of each of the parts mentioned previously, e.g.: QString authority () const; QString host () const; QString scheme () const; void setUserName ( const QString & userName ); Simplest way to create a QUrl object is to pass it a QString version of the path: QUrl url(""); QString str = url.scheme() + “://” +; if( url.path().contains(“4.7”) ) qDebug << “Using new Qt!!”;

49 QUrl The following methods of QUrl are typically used to encode/decode the URL: QByteArray toEncoded ( FormattingOptions options = None ) const; QUrl fromEncoded ( const QByteArray & input ); QByteArray toPercentEncoding ( const QString & input, const QByteArray & exclude = QByteArray(), const QByteArray & include = QByteArray() ); QString fromPercentEncoding ( const QByteArray & input ); There are also a few methods for use with relative URLs: bool isRelative () const; QUrl resolved ( const QUrl & relative ) const; QUrl baseUrl(""); QUrl relativeUrl("../products/solutions"); qDebug(baseUrl.resolved(relativeUrl).toString()); // prints ""

50 Regular expressions Regular expressions in Qt are represented by QRegExp class. QRegExp’s syntax is modeled on Perl’s regular expressions and it has full support for Unicode. QRegExp in one of several modes. These include for example: QRegExp::RegExp -- default Qt regular expressions QRegExp::Wildcard -- simple pattern matching like in shells QRegExp::FixedString -- matching with all metacharacters excaped Developers can switch between those using setPatternSyntax() method.

51 Using QRegExp After a QRegExp object is created, one can use the following methods to search through a string using the regexp: indexIn () returns position of first match searching from offset exactMatch () returns true if regexp exactly matches the string lastIndexIn () -- returns position of first match searching backwards from offset cap () returns text captured by n-th subexpression pos() returns the position of text captured by n-th subexpression capturedTexts() returns a list of texts captured by subexpressions

52 Building regexps Regexps are built up from expressions, quantifiers, and assertions. Expression examples: x, somestring, word, xlaslkxal9878 [abcd], [xyz], [aeiouy] // means: a or b or c or d [a-z], [1-4], [0-9] // means: a character from the set a-z Quantifier examples: {1} or {1,1} // means: once and exactly once {1,3} // means: once, twice or three times The two above combined: [0-9]{1,2} // one or two digits [A-Za-z]{0,5} // maximum five upper- or lowercase letters

53 Building regexps Assertion examples: Grouping expressions together:
^ // (when at the beginning) means: must match from the beginning $ // (when at the end) means: must match to the end \b // means: expression inside must be a separate word Grouping expressions together: (button|label) // means: match everything that contains ‘button’ or ‘label’ (?:button|label) // means: same as above, but does not capture text \b(button|label)\b // means: match word ‘button’ or word ‘label’ Other quantifiers: ? // means: zero or one occurrences of + // means: one or more occurrences of * // means: zero or more occurrences of

54 Building regexps Abbreviations for sets of characters: Some more:
. // matches any character \d // matches any digit \D // matches any non-digit \s // matches any whitespace character \S // matches any non-whitespace character \w // matches any word character - letters, numbers, marks, ‘_’ \W // matches a non-word character \1, \2, … // matches backreferences - words previously captured by () Some more: [^ab] // means: match any character except ‘a’ or ‘b’

55 Regular expressions examples
int i; bool b; QRegExp exp("\\S+"); i = exp.indexIn(“hello world”); // returns 0 QStringList texts = exp.capturedTexts(); // contains “hello” QString cap1 = exp.cap(1); // returns “hello” b = exp.exactMatch(“hello world”); // returns false QRegExp exp("^\\S+$"); i = exp.indexIn(“hello world"); // returns -1 (no match) b = exp.exactMatch(“hello world”); // returns false i = exp.indexIn(“withoutSPACES"); // returns 0 b = exp.exactMatch(“withoutSPACES”); // returns true; QRegExp rxlen("(\\d+)(?:\\s*)(cm|inch)"); int pos = rxlen.indexIn(“Width: cm"); if (pos > -1) { QString value = rxlen.cap(1); // “155" QString unit = rxlen.cap(2); // "cm" // ... }

56 Regular expressions examples
QRegExp exp("\\S+"); QString str("this is a random sentence with spaces in it"); int pos = 0; while((pos = exp.indexIn(str,pos)) != -1){ qDebug() << exp.cap(0) << pos; pos += exp.matchedLength(); } QString name, city, country; exp.setPattern("^([^;]+);([^;]+);([^;]+)$"); if (exp.indexIn(“Matti Korhonen;Oulu;Finland") != -1) { name = exp.cap(1); city = exp.cap(2); country = exp.cap(3); } QRegExp exp("*.exe"); exp.setPatternSyntax(QRegExp::Wildcard); exp.exactMatch(“system.exec"); // returns false exp.exactMatch(“myapp.exe"); // returns true

57 Input validation Qt graphical applications often are required to validate user input and restrict the range of characters that can be introduced. When inputting a phone number, only digits and ‘+’, ‘-’ signs may be allowed When retrieving a URL address from the user, it should have appropriate format Some widgets may require users to provide a double - letters and punctuation marks should be discarded Qt provides abstract QValidator class and its subclasses for this purpose: QIntValidator QDoubleValidator QRegExpValidator

58 Input validation To apply certain way of validating input to QLineEdit widget do the following steps: Create an appropriate QValidator subclass object Assign the validator to the widget using setValidator() When used with widgets, regular expressions in QRegExpValidator are treated as if they had ^ at the beginning and $ at the end. QValidator* validator = new QIntValidator(100, 999, this); QValidator* validator = new QDoubleValidator(0.0, 10.0, 3, this); QRegExp rx("[1-9]\\d{0,3}"); // the validator treats the regexp as "^[1-9]\\d{0,3}$" QRegExpValidator v(rx, this); QLineEdit *edit = new QLineEdit(this); edit->setValidator(validator); validator.validate(“1000”, 0); // returns QValidator::Invalid

59 QValidator Internally QValidator contains two virtual functions which can be used to implement custom validators: virtual void fixup ( QString & input ) const; virtual State validate ( QString & input, int & pos ) const; Validate() method is responsible for checking the input starting from position pos and returning one of the constants: QValidator::Invalid QValidator::Intermediate QValidator::Acceptable Fixup() attempts to fix user input according to some custom rules specific to given validator.

60 Timers in Qt

61 Basic timer support Basic timer support is implemented in QObject class, so that any its subclass can easily use it if it is needed. Methods used for this purpose are the following: int QObject::startTimer ( int interval ); void QObject::killTimer ( int id ); startTimer() returns a timer ID, which is later used to stop the timer using killTimer() and to distinguish timer events originating from particular timer. After starting the timer, QTimerEvents are delivered to the object repeatedly every interval milliseconds until timer is stopped. To handle the events, override: void QObject::timerEvent ( QTimerEvent * event );

62 QTimer The main API for the timer functionality is QTimer.
This class provides repetitive and one-time timers that emit a signal - timeout() - when the timer fires. A typical way to use a timer in Qt application is as follows: QTimer* timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(doSomething())); timer->start(1000); Such a timer will fire repeatedly every 1000 milliseconds, although the accuracy in practice depends on the operating system and application’s granularity.

63 Single shot timers If a single shot timer is needed rather than a repetitive one, one can change this behavior by using setSingleShot() method: QTimer* timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(doSomething())); timer->setSingleShot(true); timer->start(1000); Alternatively, QTimer provides a static function to simplify the code drastically. The above could be rewritten as follows: QTimer::singleShot(1000, this, SLOT(doSomething()));

64 Other QTimer methods Apart from the functions presented an previous slides, QTimer also allows developers to: Check its state using isActive() Retrieve its ID using timerId() Set the interval using setInterval() Start the timer without specifying the interval - start() The default interval is 0. Starting a timer with 0 interval will cause it to fire as soon as all the events in the window system's event queue have been processed. In effect, it’s like running a method asynchronously at a later time, when processor is not busy with anything else.

65 QBasicTimer Qt provides also a smaller, lightweight, low-level class called QBasicTimer, which sends events to specified objects instead of emitting signals. Events will be sent repeatedly until stop() is called. The full API of this class is as follows: bool isActive () const; void start ( int msec, QObject * object ); void stop (); int timerId () const;

66 Additional references
All information about timers in Qt is presented in the following articles and documentation pages: There are also a few examples which make use of timers:

67 Printing

68 Printing in Qt Qt provides extensive cross-platform facilities for printing, primarily in form of QPrinter class. Using the printing systems on each platform, Qt applications can print to attached printers and across networks to remote printers. Qt's printing system also enables PostScript and PDF files to be generated, providing the foundation for basic report generation facilities. QPrinter class is just a special type of a QPaintDevice with support for multiple pages and double-sided output. As a result, printing in Qt is performed by painting using a QPainter.

69 QPrinter QPrinter stores a huge number of user-modifiable settings necessary to define how information will be printed out. One can adjust each setting manually using accessor functions provided by the class. E.g.: void setOrientation ( Orientation orientation ); void setDuplex ( DuplexMode duplex ); void setPaperSize ( PaperSize newPaperSize ); void setPageMargins ( qreal left, qreal top, qreal right, qreal bottom, Unit unit ); void setColorMode ( ColorMode newColorMode ); void setPrintRange ( PrintRange range ); void setCopyCount ( int count ); void setResolution ( int dpi )

70 QPrintDialog In many contexts, it is better to ask the user to specify all details where and how the document should be printed. In that case, Qt provides a dialog for adjusting the values of all printer-related options - QPrintDialog. The dialog is typically used like this: QPrinter printer; QPrintDialog *dialog = new QPrintDialog(&printer, this); dialog->setWindowTitle(tr(“Printing example")); if (editor->textCursor().hasSelection()) dialog->addEnabledOption(QAbstractPrintDialog::PrintSelection); if (dialog->exec() != QDialog::Accepted) return;

71 Printing After QPainter object’s properties have been set to appropriate values, one can start painting in the following way: QPainter painter; painter.begin(&printer); for (int page = 0; page < numberOfPages; ++page) { // Use the painter to draw on the page if (page != lastPage) printer.newPage(); } painter.end(); Notice that newPage() method is used to create a new blank page in preparation for drawing on it. Drawn elements will be sent to the printer or written to a file after painter.end() is called.

72 Printing to a file There are two methods which can be used to redirect the output of QPrinter to a postscript or pdf file: void QPrinter::setOutputFileName ( const QString & fileName ); void QPrinter::setOutputFormat ( OutputFormat format ); If an output file name has been specified, printing will occur to a file. Otherwise, data will be sent to the printer. Output format is automatically set to PdfFormat or PostScriptFormat based on the extension of the file name provided to setOutputFileName(). If extension is other than ‘.ps’ or ‘.pdf’, format set using this function will be used.

73 Printing complex widgets
To print a simple widget onto a QPrinter paint device, one must use one of the render() functions provided by QWidget class. In more complex widgets, it is frequent that their content is managed by a separate helper class, and that specific class’s methods need to be used for printing. Examples: // setup a QPrinter and a QPainter painter.begin(&printer); QTextEdit* text = …; QTextDocument* document = text.document(); document.print(&printer); // print QTextEdit’s contents to the printer printer.newPage(); QGraphicsView* view = …; view.render(&painter); // paint view’s contents to a new full page painter.end();

74 Additional information
Few slides about printing presented above do not exhaust the topic. For instance, there are a couple more dialog classes related to printing, which developer can make use of. Interested people can find more information here:

75 Files and streams

76 Accessing files in Qt In Qt, QFile class provides an interface for all basic file operations: Creating Reading Writing Copying - copy(QString) Renaming - rename(QString) Removing - remove() QFile is a random access I/O device (inherits QIODevice) for reading and writing text and binary files. The name of the file represented by particular QFile object is usually passed in the constructor. QFile expects the file separator to be '/' regardless of operating system.

77 Reading & writing Before any operation can be executed on the file, it needs to be opened using one of overloads of open() method. After QFile object is not needed any more, it should be closed with close(). QFile may be used for reading/writing by itself or in conjunction with Qt streams - either QDataStream or QTextStream. The following functions for reading/writing that have been inherited from QIODevice are available: read(), readLine(), readAll() peek() getChar() write() putChar() ungetChar()

78 File opening modes Example:
To open a file, one must pass a constant representing the mode in which file is to be opened. QIODevice::ReadOnly QIODevice::WriteOnly QIODevice::ReadWrite Additionally, one may pass one or more of the following flags to adjust QFile’s behavior: QIODevice::Append QIODevice::Truncate QIODevice::Text // performs end-of-line translation QIODevice::Unbuffered Example: bool success = | QIODevice::Text | QIODevice::Append);

79 Reading/writing files - examples
QFile file("in.txt"); if (! | QIODevice::Text)) return; while (!file.atEnd()) { QByteArray line = file.readLine(); // do some processing here } file.close(); #include <stdio.h> void printError(const char* msg) { QFile file;, QIODevice::WriteOnly); file.write(msg, qstrlen(msg)); // write to stderr file.close(); }

80 Other interesting methods
Setting and retrieving file access permissions: Permissions permissions( const QString & fileName ); bool setPermissions( const QString & fileName, Permissions permissions ); Checking if file exists: bool exists ( const QString & fileName ); Creating links/shortcuts: bool link ( const QString & fileName, const QString & linkName ); Moving the cursor inside the file: qint64 pos () const; bool seek ( qint64 off ); qint64 size () const;

81 Other useful methods Retrieve last error information:
FileError error () const; QString errorString () const; Checking the state and properties of the QFile object: bool isOpen () const; bool isReadable () const; bool isSequential () const; bool isTextModeEnabled () const; bool isWritable () const;

82 Qt streams Qt provides two stream classes for serialization of binary and textual data respectively: QDataStream QTextStream Qt’s stream classes provide a convenient way to read and write blocks of data to and from various I/O devices, e.g. QFile, QProcess and QTcpSocket. They implement serialization of C++'s basic data types through their >> and << operators, while serialization of compound Qt classes is performed through class-specific >> and << operators.

83 Binary streams QDataStream is used for serialization of binary data.
It encodes data in a manner which is fully independent of the host computer’s OS, CPU or byte order. Each item written to the stream is written in a predefined binary format that varies depending on the item's type. Supported Qt classes include: Container classes - QList, QMap, QVector, … Images - QImage, QPicture, QPixmap, QIcon, … Basic drawing-related classes - QColor, QBrush, QFont, QPen, … Other basic classes - QPoint, QSize, QRect, QTime, QDate, QVariant, QString, …

84 Binary streams - examples
QFile file(“binary.dat");; QDataStream out(&file); out.setVersion(QDataStream::Qt_4_0); out << QPoint(100,45) << QSize(100,100) << QRect(0,0,50,25); out << QString(“Some text in here."); out << (qint32)66; file.close();; QDataStream in(&file); in.setVersion(QDataStream::Qt_4_0); QPoint mypoint; QSize mysize; QRect myrect; QString str; qint32 i; in >> mypoint >> mysize; in >> myrect >> str >> i; qDebug() << str << i ; file.close();

85 Basic types The qtglobal.h header file declares several type definitions that guarantee a specified bit-size on all platforms supported by Qt for various basic types. The available typedefs are: qint8, qint16, qint32, qint64 quint8, quint16, quint32, quint64 These typedefs are useful when writing to and reading from streams to make sure that the same amount of data is serialized in and out independent of the platform.

86 QDataStream API In addition to << and >> operators, QDataStream provides the following useful methods: For reading bytes from stream: QDataStream & readBytes ( char *& s, uint & l ); int readRawData ( char * s, int len ); For writing bytes to stream: QDataStream & writeBytes ( const char * s, uint len ); int writeRawData ( const char * s, int len ); For adjusting stream’s characteristics: void setByteOrder ( ByteOrder bo ); void setFloatingPointPrecision ( FloatingPointPrecision precision ); Other: int skipRawData ( int len ); bool atEnd () const;

87 Text streams QTextStream class provides a convenient interface for reading and writing text through streaming operators >> and <<. Additionally, it supports formatting options for field padding and alignment, and formatting of numbers through manipulators. QTextStream is locale aware, and will automatically decode standard input using the codec set with QTextCodec::codecForLocale(). Therefore, while QFile’s readXXX methods return QByteArray 8-bit data, QTextStream’s methods return properly encoded 16-bit QString. When reading numbers from a stream of text, QTextStream will, by default, automatically detect the number's base representation. E.g. “0x22” will be interpreted as a hexadecimal value.

88 Text streams - examples
QFile file(“errors.txt"); if ( | QFile::Append) ) { QTextStream out(&file); out << “Nums: " << qSetFieldWidth(8) << right << 5.22 << ; // prints “Nums: " } QTextStream in(stdin); QString line; do { line = in.readLine(); } while ( !line.isNull() ); QFile file(“messages.txt"); if (! | QIODevice::Text)) return; QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine(); qDebug() << line; }

89 QTextStream API Some of the interesting functions available in QTextStream are: Padding and alignment: void setFieldAlignment ( FieldAlignment mode ); void setFieldWidth ( int width ); void setPadChar ( QChar ch ); Real numbers format: void setRealNumberNotation ( RealNumberNotation notation ); void setRealNumberPrecision ( int precision ); void setNumberFlags ( NumberFlags flags ); Integer base: void setIntegerBase ( int base );

90 QTextStream API Moreover, similarly to QDataStream, QTextStream also contains methods for reading from its data: QString read ( qint64 maxlen ); QString readAll (); QString readLine ( qint64 maxlen = 0 ); void flush (); bool atEnd () const; qint64 pos () const; bool seek ( qint64 pos );

91 Stream manipulators Like <iostream> in the standard C++ library, QTextStream also defines several global manipulator functions: bin, oct, dec, hex // set integer base uppercasebase, lowecasebase fixed, scientific // change floating point notation left, right, center // change alignment forcesign, noforcesign endl flush // same as in << ‘\n’; in.flush(); reset

92 Manipulators - examples
QFile file("data.txt");; QTextStream out(&file); out << fixed << << endl; // writes out << scientific << << endl; // writes e+02 out << forcesign << 100 << noforcesign << endl; // writes +100 out << showbase; out << dec << 64 << '\n' // writes 64 << oct << 64 << '\n' // writes 0100 << hex << 64 << endl; // writes 0x40 out << center << qSetFieldWidth(10) << "5"; // writes " 5 " out << right << qSetPadChar('.') << "23"; // writes " " file.close();

93 Accessing directories
QFile class in Qt represents only individual files in the file system. It cannot be used to access or iterate over directories. In Qt, QDir class is used for that purpose. It is used to manipulate path names, access information regarding paths and files, and manipulate the underlying file system. QDir uses "/" as a universal directory separator in the same way that "/" is used as a path separator in URLs. A QDir can point to a file using either a relative or an absolute path. QDir dir(“/home/user/); // absolute path QDir dir(“documents/report.pdf”); // relative path

94 Directory manipulation
The following functionality related to directories is available in QDir class: Checking existance - exists() Moving around the hierarchy - cdUp(), cd(QString) Creating - mkdir(QString), mkpath(QString) Removing - rmdir(QString), rmpath(QString) Renaming - rename(QString) Listing - entryList(), entryInfoList() Filtering - setNameFilters(QStringList), setFilter() Sorting - setSorting()

95 Directory list filtering
There are two methods that can be used to filter directory content list: void setFilter ( Filters filters ); void setNameFilters ( const QStringList & nameFilters ); setFilter() is used to specify the attributes of files that should be displayed, e.g.: QDir::Dirs QDir::Files QDir::Executable QDir::Hidden QDir::NoSymLinks With setNameFilters() one can specify a range of file names, which are to be returned, e.g.: dir.setNameFilters( QStringList() << “*.cpp” << “*.h” );

96 Retrieving special paths
QDir contains a few static methods for retrieving QDir objects representing special paths existing in the system: QDir current(); QDir home(); QDir root(); QDir temp() A few functions to retrieve paths to those directories as QString also exist: QString currentPath(); QString homePath(); QString rootPath(); QString tempPath(); It is possible to retrieve a list of drives using drives() method.

97 Relative and absolute paths
QDir class contains several functions facilitating checking if the path by which QDir was specified is absolute or relative, as well as conversion between them: bool isAbsolute () const bool isRelative () const bool QDir::makeAbsolute(); QString path () const; QString absolutePath () const; QString relativeFilePath ( const QString & fileName ) const; QString filePath ( const QString & fileName ) const; QDir dir("/home/bob"); QString s; s = dir.relativeFilePath("images/file.jpg"); // s is "images/file.jpg" s = dir.relativeFilePath("/home/mary/file.txt"); // s is "../mary/file.txt" s = dir.filePath(“images/file.jpg”); // s is “/home/bob/images/file.jpg” s = dir.filePath(“/home/mary/file.txt”); // s is “/home/mary/file.jpg”

98 Retrieving file information
While QFile and QDir class make accessing file system and managing it very easy, they do not provide interface for retrieving information about files. This functionality is available in QFileInfo class. For instance one can: Retrieve file name and path File extension: suffix() Access permissions File characteristics: isFile(), isDir(), isHidden(), isSymLink(), isReadable(), isWritable(), isExecutable(), … Last access time: lastRead(), lastModified() File size File IDs: groupId(), ownerId()

99 Monitoring file modifications
When writing multimedia application it is often necessary to observe modifications to certain files and/or directories. In Qt QFileSystemWatcher provides this functionality. It: Allows specification of files and/or directories to be monitored Sends signals when one of the monitored entities is modified void directoryChanged ( const QString & path ); void fileChanged ( const QString & path ); Monitoring file system consumes system resources, so on some systems there may be a limitation as to how many entities can be monitored simultaneously (because of a maximum number of possible open file handles).

100 Additional information
More detailed information about functionality and individual methods provided by Qt file access classes and streams is available in their class references:


102 Resourcefully yours Owner: Last update: July 2009 Insert name of speaker and date for presentation. Purpose Message Supporting notes

Download ppt "Strings, containers, I/O"

Similar presentations

Ads by Google