Jasmin Blanchette, Harald Fernengel (перевод Andi Peredri)
Сейчас уже доступна Qt 3.2. В этой версии появилось много новых классов и возможностей, которые вам бы наверняка захотелось должным образом использовать в своих Qt-приложениях. Большинство из них мы рассмотрим в этой статье. С полным списком изменений в Qt 3.2.0 можно ознакомиться здесь: Changes 3.2.0.
| Экранная заставка |
Новый класс QSplashScreen упрощает создание экранной заставки, демонстрируемой во время загрузки приложений. Этот класс во многом схож с классом SplashScreen из четвертого выпуска Qt Quarterly. Если в своих приложениях вы уже используете SplashScreen, вы можете заменить его классом QSplashScreen. При замене помните о следующем:
| Новый элемент интерфейса ToolBox |
Панель инструментов QToolBox, впервые появившаяся в Qt Designer 3.1, стала стандартным интерфейсным элементом Qt, который вы можете использовать в своих собственных программах.
В среде Windows элемент QToolBox имеет внешний вид стандартного для этой платформы элемента ToolBox. При использовании стилей Mac и Motif страницы, входящие в состав элемента, изображаются в виде вкладок.
Qt Designer обеспечивает полную поддержку элемента QToolBox. Для этого из списка интерфейсных элементов выберите ToolBox и затем поместите его в вашу форму. Теперь вы можете заполнить вкладки элемента точно так же, как заполняли раньше вкладки QTabWidget или QWidgetStack.
| Локальная область данных потока |
В много-поточных приложениях статические и глобальные переменные доступны для всех потоков. Если вы хотите, чтобы у каждого потока была своя копия данных, то используйте для хранения переменных новый шаблонный класс QThreadStorage. Этот класс обеспечивает механизм хранения локальных данных потока, известный также как Thread-Local Storage (TLS). До выхода Qt 3.2 это можно было сделать только с помощью платформо-зависимого API. Теперь это делается так:
В каких случаях может использоваться QThreadStorage? Обычно для хранения глобальных и статических переменных, к которым должен быть запрещен одновременный доступ из нескольких потоков. В качестве примера может послужить кэш, одновременный доступ к которому из нескольких потоков может привести к ошибкам. (В качестве альтернативного решения можно использовать QMutex.)
| Управление памятью в QString |
Часто увеличение длины строки QString приводит к повторному перераспределению памяти, как показано в следующем примере:
while (...) { str += getChar(); }
Такое автоматическое перераспределение памяти в классе QString является приемлемым для большинства приложений. Для более гибкого управления памятью используйте три следующих функции QString:
Эти функции не изменяют значение объекта QString, а лишь влияют на скорость его работы и использование им памяти. Ниже представлен пример, в котором вызов reserve() гарантирует, что во время работы цикла while не будет перераспределяться память, а последующий вызов squeeze() обеспечивает освобождение всей неиспользуемой памяти:
QString str; int len = 0; str.reserve(maxLen); while (...) { str[len++] = getChar(); } str.squeeze();
| QString с несколькими аргументами |
Механизм QString::arg() накладывает ограничения на использование символа % в строковых параметрах. Например, следующий код будет работать некорректно, если appName содержит %0, %1 или %2:
QString("%1 - %2").arg(appName).arg(fileName)
Для решения этой проблемы Qt 3.2 предлагает использовать перегруженную функцию arg() с различным числом строковых параметров. Вот как следует переписать этот участок кода, чтобы избежать возможных проблем:
QString("%1 - %2").arg(appName, fileName)
Функция arg() в качестве параметров может принимать до четырех строковых значений. Если вам необходимо передать нестроковое значение, например, int или float, воспользуйтесь для этого сначала одноаргументной версией arg(), а затем многоаргументной arg() для передачи строк.
| Поддержка масок в QLineEdit |
Элемент QLineEdit теперь поддерживает ввод по маске. Маска состоит из специальных символов и разделителей. Специальные символы определяют допустимый диапазон ввода, разделители всегда видимы и не могут быть изменены. Например, в маске 990.990.990.990 девятки определяют поля опционального ввода цифр, нули - поля обязательного ввода, а точки являются разделителями. Такая маска может использоваться для ввода IP-адреса, такого как 123.54.129.255.

Маски дополняют валидаторы (validators). Основная проблема валидаторов заключалась в отсутствии визуального представления. В то же время, для контроля ввода маски могут использовать разделители.
В любой момент времени вы можете проверить введенные данные на корректность с помощью функции hasAcceptableInput(). Если в поле ввода ожидалось цифровое значение, QLineEdit не позволит ввести буквенное, однако пользователь может не вводить всю необходимую информацию, и в этом случае hasAcceptableInput() возвратит false.
Более подробную информацию об используемых в масках специальных символах и примеры готовых масок можно найти в описании свойства inputMask. Наиболее простой способ поэкспериментировать с масками - запустить Qt Designer, установить для элемента QLineEdit свойство inputMask и включить предварительный просмотр формы (Ctrl+T).
| Полная поддержка индийского и сирийского языков |
В Qt 3.0 был выполнен большой объем работ, связанный с поддержкой языков с левосторонним чтением, таких как арабский, персидский и иврит. В Qt 3.2 эта поддержка была расширена на семейство индийских языков, включая бенгальский, тамильский и деванагари.

Также в список поддерживаемых языков с левосторонним чтением был добавлен сирийский. Для поддержки этих языков со стороны Windows должен использоваться Uniscribe, а со стороны X11 - XFT и шрифты OpenType.
| Угловые интерфейсные элементы в QTabWidget |

Класс QTabWidget теперь поддерживает угловые элементы с двух сторон поля вкладок. Эту возможность использует Qt Assistant для отображения слева и справа от поля вкладок кнопок добавления и удаления текущей вкладки.
| Const Begin и Const End |
Классы неявного совместного доступа (implicitly shared classes) QMap
Если вы хотите использовать эти функции в своих приложениях, найдите все вхождения const_iterator или ConstIterator, например:
QValueVector<int>::const_iterator it = vec.begin(); while (it != vec.end()) { ++it; }
и замените функции begin() и end() функциями constBegin() и constEnd():
QValueVector<int>::const_iterator it = vec.constBegin(); while (it != vec.constEnd()) { ++it; }
Также убедитесь в том, что вы используете const_iterator вместо iterator во всех случаях, когда полученные через итератор данные не модифицируются.
| QTextEdit::setMaxLogLines() |
Одним из нововведений в Qt 3.1 был режим LogText в QTextEdit. Этот режим был оптимизирован для просмотра больших текстов. Сейчас QTextEdit позволяет задать максимальное число строк текста для этого режима. Если это число будет превышено, верхние строки будут автоматически удаляться.
| Поддержка Long Long |
В настоящее время для использования в приложениях Qt предлагает переносимые предопределенные 64-битные целые типы Q_LLONG и Q_ULLONG. Поддержка Q_LLONG и Q_ULLONG в QVariant позволяет избежать конвертирования данных в строку и обратно при доступе к 64-битным полям SQL-баз данных. Также с целью поддержки 64-битных целых типов были расширены интерфейсы QString и QDataStream.
| Изменение модальности |
В классе QDialog появился новый метод setModal(bool), который делает излишним параметр bool modal конструктора этого класса. Теперь при создании собственного подкласса QDialog вам достаточно определить конструктор вида:
MyDialog(QWidget *parent = 0, const char *name = 0);
Если вам необходимо сделать диалог модальным, вы можете либо вызвать метод exec() (который всегда показывает модальный диалог), либо последовательно вызвать setModal(true) и show(). Второй подход также позволяет сделать диалог немодальным.
| About Qt |
Статическая функция QMessageBox::aboutQt() выводит диалоговое окно About Qt. В Qt 3.2 появился одноименный слот QApplication::aboutQt( ), который может быть связан непосредственно с соответствующим QAction:
aboutQtAct = new QAction(tr("About &Qt"), 0, this); connect(aboutQtAct, SIGNAL(activated()), qApp, SLOT(aboutQt()));
Это более удобно, чем создание собственного слота aboutQt(), вызывающего статическую функцию QMessageBox::aboutQt().
Помимо информирования о том, что вы используете высококачественный инструментарий, окно About Qt показывает номер версии библиотеки Qt, использованной для сборки приложения, что может быть полезным при отладке и поддержке.
| Умные Actions |
Класс QAction теперь имеет новые конструкторы, которые не требуют явного указания названия выполняемого действия. Старый стиль:
openAct = new QAction(tr("Open"), tr("&Open..."), tr("Ctrl+O"), this);
Новый стиль:
openAct = new QAction(tr("&Open..."), tr("Ctrl+O"), this);
Класс QAction достаточно умен для того, чтобы получить текст всплывающей подсказки из названия пункта меню путем удаления амперсанда ("&") и завершающих точек ("..."). В некоторых языках, например, японском, такой стиль может работать некорректно, в этих случаях используйте setToolTip().
| Местонахождение исполняемых файлов |
Функции QApplication::applicat ionDirPath() и QApplication::applicationFilePath() возвращают путевое имя каталога и путевое имя исполняемого файла соответственно. Эта информация может быть использована для определения местонахождения файлов изображений или других данных программы.
| Новые возможности SQL-модуля |
Помимо драйверов доступа к Microsoft SQL Server, MySQL, Oracle, PostgreSQL, Sybase Adaptive Server и ODBC SQL-модуль теперь включает драйвер IBM DB2 (под названием QDB2).
Класс QSqlError теперь содержит метод showMessage(), который с помощью QMessageBox может сообщить об ошибках драйвера и сервера баз данных.
Класс QSqlCursor упрощает вывод содержимого таблицы базы данных и заполнение форм редактирования. В предыдущих версиях Qt для отображения результатов JOIN вам нужно было либо наследовать QSqlCursor, либо создавать вид и привязывать к нему QSqlCursor. Новый класс QSqlSelectCursor предлагает более удобное решение. Он может быть использован для вывода результатов любого SQL-запроса SELECT. По умолчанию класс выводит данные в режиме только для чтения, однако, переопределяя соответствующие виртуальные методы, можно реализовать функции INSERT, UPDATE и DELETE.
| Включение SQL-драйверов в приложения |
Теперь ваши собственные SQL-драйверы можно включить в приложение на этапе сборки, и не компилировать их в виде отдельных плагинов. Для этого вам необходимо известить о вашем драйвере класс QSqlDatabase, так как он получает список доступных драйверов, сканируя каталог SQL-плагинов, и ему ничего не известно об SQL-драйверах, включенных в приложение. Добавление вашего драйвера осуществляется с помощью одной строки:
QSqlDatabase::registerSqlDriver( "MYDRIVER", new QSqlDriverCreator<MyDriver>());
Теперь MYDRIVER может быть использован точно так же, как и любой другой SQL-плагин Qt.
| Параметризированные запросы |
В Qt 3.1 для поддержки IN-параметров был использован механизм привязки значений. Qt 3.2 распространяет использование этого механизма для поддержки параметров OUT и INOUT. Это может быть особенно полезным при работе с сохраненными процедурами.
QSqlQuery query; query.prepare("CALL GET_NEXT_SEQ_ID(:table, :seqid)"); query.bindValue(":table", "INVOICES"); query.bindValue(":seqid", 0, QSql::Out); query.exec(); int sequenceNumber = query.boundValue(":seqid");
Переменная :table используется в качестве IN-параметра (по умолчанию). Также bindValue() поддерживает тип параметра QSql::InOut.
| Защищенный SQL |
Данные, передаваемые между клиентскими приложениями и сервером баз данных, не шифруются. Для обеспечения безопасности необходима уверенность в том, что сетевой трафик проходит по защищенным каналам. Теперь стало возможным использование защищенных SSL-соединений при работе с базами данных, поддерживающими такие соединения.
Включение шифрования должно быть активизировано перед установкой соединения с помощью QSqlDatabase::
open() i>. Вот как вы можете установить безопасное соединение с сервером MySQL:QSqlDatabase* db = new QSqlDatabase("QMYSQL3"); // Set username, host, password, etc. db->setConnectOptions("CLIENT_SSL"); if (!db->open()) { // Fallback to unencrypted connection db->setConnectOptions(""); db->open(); if (!db->open()) // Cannot connect at all }
Шифрование включается с помощью опции установки соединения с MySQL CLIENT_SSL. Опции установки соединения очищаются с помощью вызова setConnectOptions(""). К сожалению, эти опции специфичны для каждой базы данных. Например, для установки безопасного соединения с сервером PostgreSQL необходимо использовать совершенно другую опцию:
db->setConnectOptions("requiressl=1");
Несколько параметров должны быть разделены точкой с запятой. Вот пример того, как для установки соединения с сервером MySQL использовать одновременно шифрование и компрессию:
db->setConnectOptions("CLIENT_SSL;CLIENT_COMPRESS");
Обзор доступных опций установки соединения приводится в документации класса QSqlDatabase.
| Copyright © 2002 Trolltech. | Trademarks |