Оглавление
Портирование на Qt 4Этот документ описывает процесс портирования приложений с Qt 3 на Qt 4. Если вы ещё не приняли решение о портировании или не уверены в том стоит ли это делать, ознакомьтесь с основными возможностями, предлагаемыми Qt 4. За подсказками как писать код Qt 3, который легко перенести на Qt 4, смотрите также Миграция с Qt 3 на Qt 4. Остальные руководства по портированию:
Серия Qt 4 бинарно не совместима с серией 3. Это означает, что программы скомпилированные для Qt 3 нужно перекомпилировать для работы с Qt 4. Qt 4 также не полностью совместимы с Qt 3 на уровне исходных кодов, однако почти все точки несовместимости вызывают ошибки компилятора или сообщения во время выполнения (это лучше чем загадочные результаты). Qt 4 включает множество дополнительных возможностей и избавляется от устаревшей функциональности. Портирование с Qt 3 на Qt 4 требует некоторых усилий, но однажды выполненное оно делает доступным для использования в ваших приложениях значительную дополнительную производительность и гибкость Qt 4. Чтобы портировать код с Qt 3 на Qt 4:
Инструмент портирования qt3to4 заменяет вхождения классов Qt 3, которые больше не существуют в Qt 4, на соответствующие классы поддержки Qt 3; например, QListBox превратится в Q3ListBox. В какой-то момент вы можете захотеть прекратить линковку вместе с библиотекой поддержки Qt 3 (Qt3Support) и получить преимущества от новых возможностей Qt 4. В инструкциях ниже разъясняется, как это сделать для каждого класса совместимости. Кроме классов Qt3Support (таких как Q3Action, Q3ListBox и Q3ValueList), Qt 4 предоставляет функции совместимости когда старый API может сосуществовать вместе с новым. Например, QString предоставляет функцию совместимости QString::simplifyWhiteSpace(), которая реализована встроенной (inline) и которая просто вызывает QString::simplified(). Функции совместимости здесь не документированы; вместо этого они документированы в каждом классе. Если строка QT += qt3support имеется в вашем .pro-файле, qmake автоматически определит идентификатор QT3_SUPPORT, включая поддержку функций совместимости. Вы также можете определить идентификатор вручную (например, если вы не хотите компоновать с библиотекой Qt3Support), или вы можете взамен определить QT3_SUPPORT_WARNINGS, сообщая компилятору породить предупреждение при вызове функции совместимости. (Это работает только с GCC 3.2+ и MSVC 7.) Если вы зависните, сообщите в лист рассылки qt-interest. Если вы являетесь лицензированным пользователем, вы также можете связаться с командой технической поддержки Qt. Содержание: Приведение типов и типы объектовВ Qt 3 можно было использовать функцию qt_cast() чтобы определить могут ли экземпляры подклассов класса QObject безопасно приводить типы к производным типам этих подклассов. Например, если экземпляр класса QFrame передаётся в функцию, в сигнатуре которой указан указатель на QWidget в качестве аргумента, функция qt_cast() может быть использована для получения указателя на QFrame таким образом, что можно получить доступ к функциям экземпляра класса. В Qt 4 большая часть этой функциональности предоставляется функцией qobject_cast(), а дополнительные функции предоставляют также сходную функциональность для некоторых не-QObject типов:
Имена типовВ таблице ниже перечислены классы, которые были переименованы в Qt 4. Если вы компилируете свои приложения с определенным макросом QT3_SUPPORT, старые имена будут доступны. Всякий раз когда вы встречаете имя в левой части, вы можете безопасно заменить его в вашей программе на эквивалент Qt 4. Инструмент qt3to4 выполнит преобразование автоматически.
В таблице ниже перечислены перечисления и псевдонимы типов (typedefs), которые были переименованы в Qt 4. Если вы компилируете свои приложения с определенным макросом QT3_SUPPORT, старые имена будут доступны. Всякий раз когда вы встречаете имя в левой части, вы можете безопасно заменить его в вашей программе на эквивалент Qt 4. Инструмент qt3to4 выполнит преобразование автоматически.
Значения перечисленияВ таблице ниже перечислены перечисления, которые были переименованы в Qt 4. Если вы компилируете свои приложения с определенным макросом QT3_SUPPORT, старые имена будут доступны. Всякий раз когда вы встречаете имя в левой части, вы можете безопасно заменить его в вашей программе на эквивалент Qt 4. Инструмент qt3to4 выполнит преобразование автоматически. Кроме того, следующие флаги окна были либо заменены атрибутами виджета или устарели:
В Qt 4.1 флаги виджета, использовавшиеся для установки мадальности окна, были заменены на единственное перечисление, которое может быть использоваться для указания модального поведения виджетов верхнего уровня:
СвойстваНекоторые свойства были переименованы в Qt 4, чтобы сделать Qt API более последовательным и более интуитивным. Например, свойство QWidget'а - caption - было переименовано в windowTitle чтобы сделать понятным, что оно относится к заголовку показываемому в панели заголовка окна. Кроме того, система свойств была расширена чтобы разрешить переопределение свойств в подклассах с помощью макроса Q_PROPERTY(), устраняя необходимость в макросе Q_OVERRIDE(). В таблице ниже перечислены свойства, которые были переименованы в Qt 4. Случаи их вхождения в UI файлах Qt Designer автоматически преобразуются uic'ом к новым именам.
Несколько свойств Qt 3 больше не являются свойствами в Qt 4, но функции доступа все еще существуют как часть Qt 4 API. Они не используются Qt Designer'ом; единственное обстоятельство когда вам нужно беспокоиться о них - в высоко динамичных приложениях, которые используют мета-объектную систему Qt для получения доступа к свойствам. Вот список этих свойств с функциями чтения и записи, которые вы можете использовать вместо них:
Некоторые свойства в Qt 4 были удалены, но связанные с ними функции доступа предоставляются для помощи в портировании на Qt 4,если определен QT3_SUPPORT. Когда конвертируются UI файлы Qt 3 в Qt 4, uic генерирует вызовы функций совместимости с Qt 3. Обратите внимание на то, что это применимо только к свойствам библиотеки Qt3Support, т.е. свойства QT3_SUPPORT из других библиотек при конвертации UI файлов из Qt 3 в Qt 4 должны портироваться вручную. В таблице ниже перечислены эти свойства с функциями чтения и записи, которые вы можете использовать вместо них. Документация для отдельных функций разъясняет как заменить их функциями, не являющимися функциями совместимости Qt 4.
Следующие свойства Qt 3 и их функции доступа более недоступны в Qt 4. В большинстве случаев Qt 4 предоставляет аналогичную функциональность.
Явное разделение данныхQt 4 - первая версия Qt, которая не содержит классы с явным разделением данных. Все классы, которые в Qt 3 были классами с явным разделением данных, стали в Qt 4 неявно разделять данные: Это означает, что если вы получили копию экземпляра класса (используя operator=() или копирующий конструктор класса), все изменения в копии будут действовать на оригинал и наоборот. Нечего и говорить, такое поведение редко является желательным. К счастью, почти все приложения Qt 3 не зависят от явного разделения данных. При портировании, обычно вам необходимо удалить только вызовы функции detach() и/или copy(), которые уже не нужны. Если вы обдуманно полагаетесь на явное разделение данных в вашем приложении, вы можете использовать указатели или ссылки для достижения такого же результата в Qt 4. Например, если у вас есть код void asciify(QByteArray array) { for (int i = 0; i < (int)array.size(); ++i) { if ((uchar)array[i] >= 128) array[i] = '?'; } } вы можете записать его в виде void asciify(QByteArray &array) { for (int i = 0; i < array.size(); ++i) { if ((uchar)array[i] >= 128) array[i] = '?'; } } (Обратите внимание на символ & в объявлении параметра.) Отрисовка и перерисовка виджетовПри реализации пользовательских виджетов в Qt 3, можно было использовать QPainter для отрисовки на виджете внешних событий рисования. Это делает возможным интеграцию приложений Qt со сторонними библиотеками и инструментами, которые навязывают свои модели визуализации. Например, виджет должен быть перерисован в слоте с использованием данных, полученных из внешнего источника. В Qt 4, возможно только рисование на виджете изнутри его функции-обработчика paintEvent(). Это ограничение упрощает взаимодействие Qt с "родными" оконными системами, улучшает быстродействие приложений уменьшая количество операций перерисовки, а также разрешает реализацию свойств для улучшения внешнего вида виджетов, таких как фоновое сохранение. Обычно мы рекомендуем перепроектировать приложения для выполнения всех операций рисования в функции paintEvent(), откладывая реальное рисование до следующего вызова этой функции. Приложения могут отправлять события рисования для запуска перерисовки и, возможно, для опроса внутреннего состояния вашего виджета чтобы определить, какую часть виджета необходимо перерисовать. Если вашим приложением использовались в значительной степени асинхронные перерисовки и перепроектирование модели визуализации для выполнения всех операций рисования изнутри функции paintEvent() виджета нереально, возможно придется подумать об использовании промежуточного этапа рисования. При этом подходе одно или более изображений может быть обновлено асинхронно и нарисованы на виджете в событии рисования. Чтобы избежать чрезмерной буферизации может быть стоящим отключение фонового сохранения путем установки у виджета атрибута виджета Qt::WA_PaintOnScreen. На некоторых платформах атрибут виджета Qt::WA_PaintOutsidePaintEvent можно установить чтобы разрешить отрисовку виджета извне событий рисования. Замечание: Установка атрибутов виджета для отключения основных средств модели визуализации виджета Qt может также привести к отключению других функций. Совместимость сигналов и слотовКогда определен QT3_SUPPORT, типом соединения по умолчанию для сигналов и слотов является тип Qt::AutoCompatConnection. Это позволяет так называемые совместимые сигналы и слоты (определенный в режиме поддержки Qt 3 для предоставления возможностей совместимости с Qt 3) для соединения с другими сигналами и слотами. Однако, если Qt скомпилирована с разрешенным выводом отладочной информации, и разработчик использует другие типы соединения для присоединения к совместимым сигналам и слотам (возможно, собрав свои приложения без включенной поддержки Qt 3), тогда Qt будет выводить предупреждения на консоль чтобы показать, что совместимые соединения были установлены. Это предназначено для использования в качестве помощи в процессе портирования приложения Qt 3 на Qt 4. QAccelКласс QAccel был переименован в Q3Accel и перемещен в модуль Qt3Support. В новых приложения у вас есть три варианта:
Класс Q3Accel также поддерживает многочисленные быстрые клавиши используя один и тот же объект, многократно вызывая Q3Accel::insertItem(). В Qt 4 решение заключается в создании нескольких объектов QShortcut. QAccessibleInterfaceКласс QAccessibleInterface подвергся в Qt 4 некоторым изменениям API для того, чтобы сделать его более согласованным с остальным Qt API. Если у вас есть классы, которые унаследованы от QAccessibleInterface или одного из его подклассов (QAccessibleObject, QAccessibleWidget и т.д.), вы должны портировать их на новый API QAccessibleInterface. Смотрите в Виртуальных функциях список виртуальных функций-членов QAccessibleInterface в Qt 3, которые больше не являются виртуальными в Qt 4. QAccessibleTitleBarQAccessibleTitleBar был переименован в Q3AccessibleTitleBar и перемещен в библиотеку Qt3Support. QActionКласс QAction был перепроектирован в Qt 4 чтобы лучше интегрироваться с другими системами меню. Он объединяет старые классы QMenuItem и QAction в один класс, избегая излишнего дублирования данных и необходимости изучать два разных API. Старые классы QAction и QActionGroup были переименованы в Q3Action и Q3ActionGroup, соответственно, и перемещены в Qt3Support. Кроме того, новый класс QAction имеет функции совместимости для облегчения перехода на Qt 4. Обратите внимание на то, что при использовании Q3ToolBar и Q3PopupMenu их действия должны быть объектами Q3Action. Смотрите в Виртуальных функциях список виртуальных функций-членов QAction в Qt 3, которые больше не являются виртуальными в Qt 4. QActionGroupКласс QAction был полностью перепроектирован в Qt 4 чтобы лучше интегрироваться с другими системами меню. За подробностями обращайтесь к разделу в QAction. QApplicationКласс QApplication был разделен на два класса: QCoreApplication и QApplication. Новый класс QApplication унаследован от QCoreApplication и добавляет функциональность, связанную с ГПИ. Фактически, это не имеет последствий для имеющихся приложений Qt. Кроме того, были сделаны следующие изменения API:
QAquaStyleКласс QAquaStyle впервые появился в Qt 3.0, когда впервые был выпущен порт Qt для Mac OS X. Он эмулировал тему "Aqua" от Apple. В Qt 3.1, QAquaStyle устарел с появлением QMacStyle, который использует Appearance Manager для выполнения своей отрисовки. Класс QAquaStyle более не предоставляется в Qt 4. Используйте вместо него QMacStyle. QAsciiCache<T>QAsciiCache<T> был переименован в Q3AsciiCache<T> и перемещен в библиотеку Qt3Support. Его заменил класс QCache<QByteArray, T>. Подробности читайте в разделе в QCache<T>, заменяя в уме QByteArray на QString. QAsciiDict<T>QAsciiDict<T> и QAsciiDictIterator<T> были переименованы в Q3AsciiDict<T> и Q3AsciiDictIterator<T>, соответственно, и перемещены в библиотеку Qt3Support. Их заменили более современные классы QHash<Key, T> и QMultiHash<Key, T>, соответственно, и их соответствующие классы-итераторы. При портировании на Qt 4 старого кода, который использует Q3AsciiDict<T>, имеется четыре класса, которые вы можете использовать:
Подробности читайте в разделе в QDict<T>, заменяя в уме QByteArray на QString. QAsyncIOКласс QAsyncIO использовался для внутренних нужд в Qt 2.x в сочетании с QImageConsumer. Он устарел в Qt 3.0. Если вы использовали этот механизм в своем приложении, пожалуйста, отправьте сообщение в Task Tracker на веб-сайте Qt и мы попытаемся найти удовлетворительную замену. QBackInsertIteratorНедокументированный класс QBackInsertIterator был удален из библиотеки Qt. Если он необходим в вашем приложении, просто скопируйте исходный код из заголовочного файла <qtl.h> Qt 3. QBitArrayВ Qt 3 QBitArray унаследован от QByteArray. В Qt 4 QBitArray - полностью независимый класс. Это приводит к очень небольшим отличиям для пользователя, за исключением того, что новый класс QBitArray больше не предоставляет любых API QByteArray'а, основанных на байтах. Эти вызовы приведут к появлению ошибки времени компиляции, за исключением вызовов QBitArray::truncate(), чей параметр был количеством байт в Qt 3 и количеством бит в Qt 4. В Qt 3 QBitArray был классом с явным разделением данных. Для получения дополнительной информации смотрите Явное разделение данных. Класс QBitVal был переименован в QBitRef. QButtonКласс QButton был заменен классом QAbstractButton в Qt 4. Классы, такие как QPushButton и QRadioButton, унаследованы от QAbstractButton. В качестве помощи при портировании старых приложений Qt, библиотека Qt3Support содержит класс Q3Button, реализованный на основе нового класса QAbstractButton. Если вы использовали класс QButton в качестве базового класса для ваших кнопок собственного типа и хотите перенести свой код на новый QAbstractButton, вам нужно знать, что в QAbstractButton нет эквивалента для виртуальной функции Q3Button::drawButton(QPainter *). Решением является переопределение QWidget::paintEvent() в вашем подклассе QAbstractButton как приведено ниже: void MyButton::paintEvent(QPaintEvent *) { QPainter painter(this); drawButton(&painter); }
Замечания:
Смотрите в Виртуальных функциях список виртуальных функций-членов QButton в Qt 3, которые не являются виртуальными в Qt 4. Смотрите в Свойствах список свойств QButton в Qt 3, которые изменились в Qt 4. QButtonGroupКласс QButtonGroup был полностью перепроектирован в Qt 4. Для совместимости старый класс QButtonGroup был переименован в Q3ButtonGroup и перемещен в Qt3Support. Аналогично, вспомогательные подклассы QHButtonGroup и QVButtonGroup были переименованы в Q3HButtonGroup и Q3VButtonGroup, соответственно, и перемещены в библиотеку Qt3Support. Старый класс QButtonGroup, также как и Q3ButtonGroup, можно использовать двумя способами:
В отличие от Q3ButtonGroup, новый класс QButtonGroup не унаследован от QWidget. Он очень похож на "скрытый Q3ButtonGroup". Если вы используете Q3ButtonGroup, Q3HButtonGroup или Q3VButtonGroup в качестве виджета и хотите портировать на Qt 4, вы можете заменить его на QGroupBox. В Qt 4 радио-кнопки с одним и тем же родителем автоматически становятся частью одной группы, так что вам обычно не нужно делать что-нибудь еще. Смотрите также раздел в QGroupBox ниже. Смотрите в Виртуальных функциях список виртуальных функций-членов QButtonGroup в Qt 3, которые больше не являются виртуальными в Qt 4. QByteArrayВ Qt 3 QByteArray был просто псевдонимом (typedef) для QMemArray<char>. В Qt 4 QByteArray - отдельный класс с высокоуровневым API в стиле QString. Вот основные известные проблемы при портировании на Qt 4:
В Qt 3 QByteArray был классом с явным разделением данных. Для получения дополнительной информации смотрите Явное разделение данных. QCache<T>QCache<T> переименован в Q3Cache<T> и перенесен в Qt3Support. Новый класс QCache имеет другой API и получает другой шаблон параметров: QCache<Key, T>. При портировании на Qt 4, QCache<QString, T> является очевидной заменой для Q3Cache<T>. В следующей таблице приведены различия в API.
Замечания:
QCacheIterator<T> был переименован в Q3CacheIterator<T> и перемещен в библиотеку Qt3Support. Новый класс QCache не предлагает никаких типов итераторов. QCanvasКлассы модуля canvas были переименованы и перемещены в библиотеку Qt3Support.
Каркас Графического представления заменил QCanvas. Подробности о портировании на Графическое представление смотрите в Переход на Графическое представление. QColorВ Qt 4 QColor является типом-значением наподобие QPoint или QRect. Код, зависимый от графической системы, был реализован в QColormap. Функция QColor::maxColors() заменена функцией QColormap::size(). Функция QColor::numBitPlanes() заменена функцией QColormap::depth(). Функция QColor::setNamedColor() больше не поддерживает именованные цвета тем способом, как это было в Qt 3. Функция setNamedColor() в Qt 4 использует новое соглашение W3C, как указано здесь. Предварительно определенные цвета, приведенные в таблице выше, были статическими объектами QColor в Qt 3. В Qt 4 они являются значениями перечисления типа Qt::GlobalColor. Благодаря неявному конструктору QColor(Qt::GlobalColor), в большинстве контекстов значения перечисления автоматически конвертируются в объекты QColor. Изредка вам может понадобиться приведение типа. Например, если у вас есть код QColor lightCyan = Qt::cyan.light(180); вы можете записать его в виде QColor lightCyan = QColor(Qt::cyan).light(180); QColorGroupВ Qt 3 QPalette состоял из трех объектов QColorGroup. В Qt 4 (редко используемая) абстракция QColorGroup была удалена. Для совместимости на уровне исходных кодов, класс QColorGroup доступен когда определен QT3_SUPPORT. Новый QPalette продолжает работать на основе цветовых групп, указанных посредством значений перечисления (QPalette::Active, QPalette::Disabled и QPalette::Inactive). В нем также имеется концепция текущей цветовой группы, которую вы можете установить используя QPalette::setCurrentColorGroup(). Объект QPalette, возвращенный QWidget::palette(), возвращает QPalette, инициализированную корректной текущей цветовой группы для виджета. Это означает, что если у вас есть код наподобие такого painter.setBrush(colorGroup().brush(QColorGroup::Text)); то вы можете просто заменить colorGroup() на palette(): painter.setBrush(palette().brush(QPalette::Text)); QColorDragКласс QColorDrag был переименован в Q3ColorDrag и перемещен в библиотеку Qt3Support. В Qt 4 используйте взамен QMimeData и вызовите QMimeData::setColor() для установки цвета. QComboBoxВ Qt 3 список выбора использовался для вывода на экран содержимого виджета QComboBox, получить доступ к нему можно используя функцию listBox(). В Qt 4 стандартный список выбора предоставляется виджетом QListView, и можно получить доступ с помощью функции view(). Смотрите в Виртуальных функциях список виртуальных функций-членов QComboBox в Qt 3, которые больше не являются виртуальными в Qt 4. QCStringВ Qt 3 QCString наследовался от QByteArray. Основной недостаток этого подхода заключается в том, что пользователь несет ответственность за обеспечение того, что строка является нуль-терминированной. Другой важной проблемой было то, что преобразования между QCString и QByteArray часто дают сбивающие с толку результаты. (Смотрите обзор подводных камней в статье Внимание! Бинарные и символьные данные в Qt Quarterly.) Qt 4 решает эту проблему объединив классы QByteArray и QCString в один класс с именем QByteArray. Большинство функций, которые до этого были в QCString, были перемещены в QByteArray. С проблемой символа '\0' справились выделением в QByteArray одного дополнительного байта, который всегда установлен равным '\0'. Например: QByteArray ba("Hello"); ba.size(); // возвращает 5 (символ '\0' не считаем) ba.length(); // возвращает 5 ba.data()[5]; // возвращает '\0' Библиотека Qt3Support содержит класс с именем Q3CString, который унаследован от нового класса QByteArray и который расширяет его для предоставления API, близкого к старому классу QCString настолько, насколько возможно. Обратите внимание на то, что следующие функции не представляются Q3CString:
Следующие функции потеряли свой последний аргумент, который указывает был ли поиск чувствительным к регистру или нет:
В обоих случаях решением является преобразование QCString в QString и использовании взамен соответствующих функций QString. Также знайте, что QCString::size() (унаследовано от QByteArray) использовался для возвращения размера символьных данных включая '\0'-терминатор, тогда как новая QByteArray::size() является только синонимом для QByteArray::length(). Это принесет QByteArray в строке с QString. При портировании на Qt 4 вхождения QCString должны быть заменены на QByteArray или QString. В следующей таблице приведены отличия в API между классом Q3CString и классами QByteArray и QString Qt 4:
Замечания:
Так как старый класс QCString унаследован от QByteArray, все что сказано в разделе QByteArray также применимо и для QCString. QCustomEventВ Qt 3 разработчики могли создать пользовательское событие создавая новый QCustomEvent, и отправляя соответствующие данные другим компонентам в приложении передавая указатель void, либо на структуру, либо используя функцию setData(). Объекты могут получать пользовательские события, переопределив функцию customEvent() и получив доступ к сохраненным данным, используя функцию data() события. В Qt 4 пользовательские события создаются созданием подклассов QEvent. Данные зависимые от событий могут быть сохранены способом, который подходит для вашего приложения. Пользовательские события по-прежнему доставляются каждой функции-обработчику customEvent() объекта, но как объекты QEvent лучше, чем как устаревшие объекты QCustomEvent. QDataBrowserКласс QDataBrowser был переименован в Q3DataBrowser и перемещен в библиотеку Qt3Support. В Qt 4.2 вы должны использовать класс QDataWidgetMapper для создания дата-ориентированных (data-aware) форм. Обзор новых классов SQL смотрите в Модуле QtSql. QDataPumpКласс QDataPump использовался для внутренних нужд в Qt 2.x в сочетании с QImageConsumer. Он устарел в Qt 3.0. Если вы использовали этот механизм в своем приложении, пожалуйста, отправьте сообщение в Task Tracker на веб-сайте Qt и мы попытаемся найти удовлетворительную замену. QDataSinkКласс QDataSink использовался для внутренних нужд в Qt 2.x в сочетании с QImageConsumer. Он устарел в Qt 3.0. Если вы использовали этот механизм в своем приложении, пожалуйста, отправьте сообщение в Task Tracker на веб-сайте Qt и мы попытаемся найти удовлетворительную замену. QDataSourceКласс QDataSource использовался для внутренних нужд в Qt 2.x в сочетании с QImageConsumer. Он устарел в Qt 3.0. Если вы использовали этот механизм в своем приложении, пожалуйста, отправьте сообщение в Task Tracker на веб-сайте Qt и мы попытаемся найти удовлетворительную замену. QDataTableКласс QDataTable был переименован в Q3DataTable и перемещен в библиотеку Qt3Support. В Qt 4.2 вы должны использовать класс QDataWidgetMapper для создания дата-ориентированных (data-aware) форм. Обзор новых классов SQL смотрите в Модуле QtSql. QDataViewКласс QDataView был переименован в Q3DataView и перемещен в библиотеку Qt3Support. В Qt 4.2 вы должны использовать класс QDataWidgetMapper для создания дата-ориентированных (data-aware) форм. Обзор новых классов SQL смотрите в Модуле QtSql. QDateEditВ Qt 4 класс QDateEdit является вспомогательным классом, основанным на QDateTimeEdit. Старый класс был переименован в Q3DateEdit и перемещен в библиотеку Qt3Support. Смотрите в Виртуальных функциях список виртуальных функций-членов QDateEdit в Qt 3, которые больше не являются виртуальными в Qt 4. QDateTimeEditBaseКласс QDateTimeEditBase был переименован в Q3DateTimeEditBase и перемещен в Qt3Support. Вместо этого используйте QDateTimeEdit или QAbstractSpinBox. QDateTimeEditСтарый класс QDateTimeEdit был переименован в Q3DateTimeEditBase и перемещен в Qt3Support. Новый класс QDateTimeEdit в Qt 4 был переписан с нуля для предоставления большей гибкого и мощного API. Смотрите в Виртуальных функциях список виртуальных функций-членов QDateTimeEdit в Qt 3, которые больше не являются виртуальными в Qt 4. QDeepCopy<T>Класс QDeepCopy<T> в Qt 3 предоставлял способ обеспечения того, что неявно разделяющие данные и явно разделяющие данные классы указывают на уникальные данные. Это было необходимо поскольку подсчет ссылок в контейнерных классах Qt был сделан потоконебезопасным способом. Начиная с Qt 4 QDeepCopy<T> был переименован в Q3DeepCopy<T> и перемещен в библиотеку Qt3Support. Удаление его из существующего кода не вызывает затруднений. Например, если у вас есть код QString str1 = "I am a string"; QDeepCopy<QString> str2 = str1; QString str3 = QDeepCopy<QString>(str2); вы можете записать его в виде QString str1 = "I am a string"; QString str2 = str1; QString str3 = str2; QDialСмотрите в Виртуальных функциях список виртуальных функций-членов QDial в Qt 3, которые больше не являются виртуальными в Qt 4. Смотрите в Свойствах список свойств QDial в Qt 3, которые изменились в Qt 4. QDict<T>QDict<T> был переименован в Q3Dict<T> и перемещен в Qt3Support. Его заменили более современные классы QHash<Key, T> и QMultiHash<Key, T>. При портировании на Qt 4 старого кода, использующего QDict<T> имеется четыре класса, которые вы можете использовать:
API Q3Dict<T> и QMultiHash<QString, T *> очень похожи. Основной проблемой является то, что Q3Dict поддерживает автоудаление тогда как QMultiHash - нет. В следующей таблице приведены различия в API между двумя классами:
Замечания:
Если вы используете возможность Q3Dict'а -автоудаление (вызывая Q3Dict::setAutoDelete(true)), вам нужно сделать немного больше работы. У вас есть два варианта: Вы либо сами вызываете delete всякий раз, когда удаляете элемент из контейнера, либо вы используете QMultiHash<QString, T> вместо QMultiHash<QString, T *> (т.е. сохраняете непосредственно значения вместо указателей на значения). Здесь мы увидим когда вызвать delete. В следующей таблице приведены стили, которые вам нужно знать, если вы хотите сами вызывать delete.
Имейте в виду, что деструктор Q3Dict'а автоматически вызывает clear(). Если у вас в пользовательском классе имеется член данных Q3Dict и вы используете возможность автоудаления, то чтобы избежать утечки памяти вам будет нужно вызывать из деструктора вашего класса delete для всех элементов контейнера. В заключение, QDictIterator<T> (переименованный Q3DictIterator<T>) должен также быть портирован. Имеется не менее четырех классов-итераторов, которые могут использоваться в качестве замены: QHash::const_iterator, QHash::iterator, QHashIterator и QMutableHashIterator. Проще всего использовать при портировании класс QHashIterator<QString, T *>. В следующей таблице приведены различия в API.
Знайте, что QHashIterator имеет другой способ перебора элементов, чем Q3DictIterator. Типичный цикл с Q3DictIterator выглядит примерно так: Q3DictIterator<QWidget> i(dict); while (i.current() != 0) { do_something(i.currentKey(), i.current()); ++i; } Here's the equivalent QHashIterator loop: QHashIterator<QString, QWidget *> i(hash); while (i.hasNext()) { i.next(); // должен быть в начале do_something(i.key(), i.value()); } За подробностями обращайтесь к Итераторам в стиле Java. QDirСледующие используемые функции имеют булев параметр acceptAbsPath, который по умолчанию равен true:
В Qt 3, если acceptAbsPath равен true, имя файла начинающееся с '/' возвращалось без изменений; если acceptAbsPath равен false, в начало имени файла добавляется абсолютный путь. Например:
В Qt 4 этот параметр больше не доступен. Если вы используете это в вашем коде, вы можете проверить что QDir::isRelativePath() возвращает взамен false. Например, если у вас есть код QDir dir("/home/tsmith"); QString path = dir.filePath(fileName, false); вы можете записать его в виде QDir dir("/home/tsmith"); QString path; if (dir.isRelativePath(fileName)) path = dir.filePath(fileName); else path = fileName; QDir::encodedEntryList() была удалена. fileInfoList(), entryInfoList() и drives() возвращают теперь QList<QFileInfo>, а не QPtrList<QFileInfo> *. Код, использующий эти методы, не будет работать с библиотекой Qt3Support и вместо этого должен быть адаптирован. Смотрите в Виртуальных функциях список виртуальных функций-членов QDir в Qt 3, которые больше не являются виртуальными в Qt 4. Совпадения QDir::match() теперь всегда нечувствительны к регистру. QDir::homeDirPath() была удалена. Вместо этого используйте QDir::home() и извлекайте путь отдельно. QDnsQt 3 использовал свою собственную реализацию протокола DNS и предоставлял низкоуровневый класс QDns. Вместо этого класс Qt 4 QHostInfo использует системную функцию gethostbyname() из потока. Старый класс QDns был переименован в Q3Dns и перемещен в библиотеку Qt3Support. Новый класс QHostInfo имеет совершенно другой API: Он состоит главным образом из двух статических функций, одна из которых блокирующая (QHostInfo::fromName()), а другая неблокирующая (QHostInfo::lookupHost()). За подробностями обращайтесь к документации класса QHostInfo. QDockAreaКласс QDockArea был переименован в Q3DockArea и перемещен в библиотеку Qt3Support. В Qt 4 QMainWindow самостоятельно обрабатывает области присоединения и панели инструментов. За подробностями обращайтесь к документации QMainWindow. QDockWindowСтарый класс QDockWindow был переименован в Q3DockWindow и перемещен в библиотеку Qt3Support. В Qt 4 имеется новый класс QDockWidget с отличающимся API. За подробностями обращайтесь к документации класса. Смотрите в Виртуальных функциях список виртуальных функций-членов QDockWidget в Qt 3, которые больше не являются виртуальными в Qt 4. Замечание: Свойство Q3DockWindow'а, horizontallyStretchable, может быть реализуется в QDockWidget с помощью политик размера. QDragObjectКласс QDragObject был переименован в Q3DragObject и перемещен в библиотеку Qt3Support. В Qt 4 его заменил класс QMimeData. За подробностями обращайтесь к документации класса. Обратите внимание на то, что режим перетаскивания Q3DragObject::DragCopyOrMove интерпретируется иначе, чем режим QDragObject::DragCopyOrMove в Qt 3. В Qt 3 операция перемещения выполнялась по умолчанию, а для выполнения операции копирования пользователь удерживал нажатой клавишу Ctrl. В Qt 4 по умолчанию выполняется операция копирования; для выполнения операции перемещения пользователь удерживает нажатой клавишу Shift. Смотрите Портирование на Qt 4 - Перетаскивание для сравнения API перетаскивания в Qt 3 и Qt 4. QDropSiteКласс QDropSite был переименован в Q3DropSite и перемещен в библиотеку Qt3Support. Класс QDropSite устарел еще со времен Qt 2.0. Все что он делает - вызывает QWidget::setAcceptDrops(true). Например, если у вас есть код class MyWidget : public QWidget, public QDropSite { public: MyWidget(const QWidget *parent) : QWidget(parent), QDropSite(this) { } ... } вы можете записать его в виде class MyWidget : public QWidget { public: MyWidget(const QWidget *parent) : QWidget(parent) { setAcceptDrops(true); } ... } Смотрите Портирование на Qt 4 - Перетаскивание для сравнения API перетаскивания в Qt 3 и Qt 4. QEditorFactoryКласс QEditorFactory был переименован в Q3EditorFactory и перемещен в библиотеку Qt3Support. Обзор новых классов SQL смотрите в Модуле QtSql. QEventLoopВ Qt 3 QEventLoop сочетает цикл обработки событий Qt и диспетчеризацию событий. В Qt 4 эти задачи теперь разнесены по двум отдельным классам: QEventLoop и QAbstractEventDispatcher. Если вы создали подкласс QEventLoop для интеграции с циклом обработки событий другой библиотеки, взамен вы должны создать подкласс QAbstractEventDispatcher. За подробностями обращайтесь к документации класса. Разработчики, использовавшие QEventLoop::loopLevel() в Qt 3, должны использовать вместо нее QCoreApplication::loopLevel(). Обратите внимание на то, что эта функция помечена как устаревшая, но ожидается, что она будет доступна в течение времени жизни Qt 4. QFileDialogКласс QFileDialog был полностью переписан в Qt 4. Он предоставляет большую часть функциональности старого класса QFileDialog, но с другим API. Добавление некоторой функциональности, например, возможности предварительного просмотра файлов, ожидается в следующих выпусках Qt 4. Старые классы QFileDialog, QFileIconProvider и QFilePreview были переименованы в Q3FileDialog, Q3FileIconProvider и Q3FilePreview, соответственно, и перемещены в Qt3Support. Вы можете использовать их, если вам нужна некоторая функциональность, еще не предоставляемая новым классом QFileDialog. В следующей таблице перечислены функции, которые были переименованы или удалены в Qt 4.
Замечания:
Не имеется эквивалентных виртуальных функций для двух виртуальных функций Q3FileDialog::setSelectedFilter() в API QFileDialog. Кроме того, эти функции переименованы или удалены, как описывалось выше. QFocusDataКласс QFocusData не доступен в Qt 4. Некоторая его функциональность доступна через функции QWidget::nextInFocusChain() и QWidget::focusNextPrevChild(). QFocusEventФункции setReason() более нет в Qt 4. Необходимо определить причину при создании события фокуса. QFontQFont::Script была перемещена в QFontDatabase::WritingSystem. QFrameУменьшив в Qt 4 количество свойств и виртуальных функций класс QFrame был сделан более легким. Уменьшение количества виртуальных функций важно, поскольку QFrame является базовым классом многих классов Qt. Вот обзор изменений:
Чтобы помочь с портированием библиотека Qt3Support содержит класс Q3Frame, который унаследован от QFrame и предоставляет API, аналогичный API старого класса QFrame. Если в вашем приложении вы наследовали от QFrame, вы можете захотеть использовать Q3Frame в качестве базового класса как первый этап процесса портирования, а позднее перейти на новый класс QFrame. Смотрите в Виртуальных функциях список виртуальных функций-членов QFrame в Qt 3, которые больше не являются виртуальными в Qt 4. QFtpQFtp больше не унаследован от QNetworkProtocol. За подробностями обращайтесь к разделу в QNetworkProtocol. Старый класс QFtp был переименован в Q3Ftp и перемещен в библиотеку Qt3Support. QGLayoutIteratorКласса QGLayoutIterator больше нет в Qt 4. Это приводит к отличиям только если вы реализовали пользовательские менеджеры компоновки (т.е., создали подклассы QLayout). Новый подход значительно проще: Он состоит в переопределении QLayout::itemAt() и QLayout::takeAt(). Эти функции работают с индексами, устраняя необходимость в классе-итераторе компоновки. QGridКласс QGrid теперь доступен только как Q3Grid в Qt 4. Вы можете добиться такого же результата, что и с QGrid создав QWidget с компоновкой сетки: Например, если у вас есть код QGrid *grid = new QGrid(2, Qt::Horizontal); QPushButton *child1 = new QPushButton(grid); QPushButton *child2 = new QPushButton(grid); QPushButton *child3 = new QPushButton(grid); QPushButton *child4 = new QPushButton(grid); вы можете записать его в виде QWidget *grid = new QWidget; QPushButton *child1 = new QPushButton(grid); QPushButton *child2 = new QPushButton(grid); QPushButton *child3 = new QPushButton(grid); QPushButton *child4 = new QPushButton(grid); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(child1, 0, 0); layout->addWidget(child2, 0, 1); layout->addWidget(child3, 1, 0); layout->addWidget(child4, 1, 1); grid->setLayout(layout); QGridLayoutСмотрите в Виртуальных функциях список виртуальных функций-членов QGridLayout в Qt 3, которые больше не являются виртуальными в Qt 4. QGridViewКласс QGridView был переименован в Q3GridView и перемещен в библиотеку Qt3Support. В Qt 4 мы рекомендуем использовать для представления табличных данных QTableView или QAbstractItemView. Обзор новых классов представления элементов смотрите в Программирование модель/представление. QGroupBoxКласс QGroupBox был перепроектирован в Qt 4. Многие из функциональных возможностей старого класса QGroupBox можно получить использовав класс Q3GroupBox из библиотеки Qt3Support. Новый QGroupBox более легкий. Он не пытается дублировать функциональность, уже предоставляемую QGridLayout, и он не унаследован от QFrame. В результате, следующие члены были удалены:
Естественно, свойства columns и orientation также удалены. Если ваше приложение зависит от недостающей функциональности, в качестве помощи при портировании вы можете использовать Q3GroupBox вместо QGroupBox. Смотрите в Виртуальных функциях список виртуальных функций-членов QGroupBox в Qt 3, которые больше не являются виртуальными в Qt 4. QHBoxКласс QHBox теперь доступен только как Q3HBox в Qt 4. Вы можете добиться такого же результата, что и с QHBox создав QWidget с горизонтальной компоновкой: Например, если у вас есть код QHBox *hbox = new QHBox; QPushButton *child1 = new QPushButton(hbox); QPushButton *child2 = new QPushButton(hbox); вы можете записать его в виде QWidget *hbox = new QWidget; QPushButton *child1 = new QPushButton; QPushButton *child2 = new QPushButton; QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(child1); layout->addWidget(child2); hbox->setLayout(layout); Обратите внимание на то, что дочерние виджеты автоматически не размещаются в компоновке виджета; вам нужно вручную добавить каждый виджет в QHBoxLayout. QHeaderКласс QHeader был переименован в Q3Header и перемещен в библиотеку Qt3Support. В Qt 4 его заменил класс QHeaderView. Обзор новых классов представления элементов смотрите в Программирование модель/представление. QHGroupBoxКласс QHGroupBox был переименован в Q3HGroupBox и перемещен в библиотеку Qt3Support. Qt 4 не предоставляет конкретного класса замены для QHGroupBox поскольку QGroupBox спроектирован виджетом обобщенного контейнера. В результате, вам нужно обеспечить вашу собственную компоновку для любых дочерних виджетов. Для получения дополнительной информации о портировании кода, который использует групповые рамки, смотрите #QGroupBox. QHttpQHttp больше не унаследован от QNetworkProtocol. За подробностями обращайтесь к разделу в QNetworkProtocol. Старые классы QHttp, QHttpHeader, QHttpRequestHeader и QHttpResponseHeader были переименованы в Q3Http, Q3HttpHeader, Q3HttpRequestHeader и Q3HttpResponseHeader, соответственно, и перенесены в библиотекуQt3Support. QIconFactoryКласс QIconFactory больше не является частью Qt. Его заменил класс QIconEngine. QIconSetКласс QIconSet больше не является частью Qt. Его заменил класс QIcon. QIconViewКлассы QIconView, QIconViewItem, QIconDrag и QIconDragItem были переименованы в Q3IconView, Q3IconViewItem, Q3IconDrag и Q3IconDragItem, соответственно, и перемещены в библиотеку Qt3Support. Вместо этого в новых приложениях Qt должен использоваться QListWidget или его базовый класс QListView, и вызывать QListView::setViewMode(QListView::IconMode) для получения внешнего вида "в виде пиктограмм". Обзор новых классов представления элементов смотрите в Программирование модель/представление. QImageDragКласс QImageDrag был переименован в Q3ImageDrag и перемещен в Qt3Support. В Qt 4 используйте взамен QMimeData и вызовите QMimeData::setImage() для установки изображения. Смотрите Портирование на Qt 4 - Перетаскивание для сравнения API перетаскивания в Qt 3 и Qt 4. QImageIOКласс QImageIO был разделена на два класса: QImageReader и QImageWriter. В таблице ниже показано соответствие двух API:
QIntCache<T>QIntCache<T> был перемещен в модуль Qt3Support. Он был заменен QCache<int, T>. Подробности читайте в разделе в QCache<T>, заменяя в уме int на QString. QIntDict<T>QIntDict<T> и QIntDictIterator<T> были перемещены в Qt3Support. Их заменили более современные классы QHash<Key, T> и QMultiHash<Key, T> и связанные с ними классы-итераторы. При портировании на Qt 4 старого кода, который использует QIntDict<T>, имеется четыре класса, которые вы можете использовать:
Подробности читайте в разделе в QDict<T>, заменяя в уме int на QString. QIODeviceAPI класса QIODevice был упрощен чтобы облегчить создание подклассов и чтобы сделать его работу более ровной с асинхронными устройствами, например, QTcpSocket и QProcess. У следующих виртуальных функциях изменилось имя или сигнатура:
Замечание: QIODevice::open(QIODevice::OpenMode) больше не является чистой виртуальной. Следующие функции больше не являются виртуальными или больше не существуют:
Флаги IO_xxx были переработаны, а защищенная функция setFlags() удалена. Большинство флагов были ликвидированы, поскольку ошибки лучше обрабатываются реализацией конкретных функций в подклассах QIODevice нежели чем через базовые классы. Флаги доступа к файла, например, IO_ReadOnly и IO_WriteOnly, были перемещены в класс QIODevice чтобы избежать загрязнения глобального пространства имен. В таблице ниже показано соответствие между флагами IO_xxx в Qt 3 и Qt 4 API:
QIODeviceSourceКласс QIODeviceSource использовался для внутренних нужд в Qt 2.x в сочетании с QImageConsumer. Он устарел в Qt 3.0. Если вы использовали этот механизм в своем приложении, пожалуйста, отправьте сообщение в Task Tracker на веб-сайте Qt и мы попытаемся найти удовлетворительную замену. QLabelQLabel больше не разрешает автоматического выравнивания по словам при использовании форматированного текста. Вы можете разрешить это вызывая QLabel::setWordWrap() или установив свойство wordWrap. Причиной этого изменения является то, что старое поведение запутывало многих пользователей. Также QLabel больше не предоставляет свойство autoResize. Взамен вы можете вызвать QWidget::setFixedSize() на метке, с QLabel::sizeHint() в качестве аргумента, всякий раз когда вы меняете содержимое QLabel. Смотрите также в Виртуальных функциях список виртуальных функций-членов QLabel в Qt 3, которые больше не являются виртуальными в Qt 4. QLayoutВ Qt 4 поля всегда обрабатываются компоновщиками; функции QLayout::setSupportsMargin() больше нет. Функция deleteAllItems() теперь доступна только если определен QT3_SUPPORT. Если вы храните элементы компоновки в QList, вы можете использовать qDeleteAll() чтобы удалить все элементы сразу. В Qt 3, для изменения поведения при изменении размеров компоновок в виджетах верхнего уровня можно было устанавливать свойство компоновки resizeMode. В Qt 4 это свойство заменено свойством QLayout::sizeConstraint, которое предоставляет больший контроль за поведением компоновки при изменении размеров. Смотрите также раздел в QLayoutIterator и раздел в QGLayoutIterator. QLayoutIteratorКласс QLayoutIterator является устаревшим в Qt 4. Он доступен только если определен QT3_SUPPORT. Его можно заменить функциями QLayout::itemAt() и QLayout::takeAt(), которые работают с индексами. Например, если у вас есть код QLayoutIterator it = layout()->iterator(); QLayoutItem *child; while ((child = it.current()) != 0) { if (child->widget() == myWidget) { it.takeCurrent(); return; ++it; } вы можете записать его в виде int i = 0; QLayoutItem *child; while ((child = layout()->itemAt(i)) != 0) { if (child->widget() == myWidget) { layout()->takeAt(i); return; } ++i; } QLineEditСмотрите в Свойствах список свойств QLineEdit в Qt 3, которые изменились в Qt 4. Значение по умолчанию свойства QLineEdit'а - dragEnabled - в Qt 3 было true. В Qt 4 значение по умолчанию равно false. Обратите внимание на то, что QLineEdit в Qt 4 более не является подклассом QFrame. Если вам нужно визуально применить стиль к однострочному редактору с рамкой, мы рекомендуем либо использовать QFrame в качестве контейнера для QLineEdit, либо настроить однострочный редактор с помощью таблиц стилей. QListBoxКлассы QListBox, QListBoxItem, QListBoxText и QListBoxPixmap были переименованы в Q3ListBox, Q3ListBoxItem, Q3ListBoxText и Q3ListBoxPixmap, соответственно, и перемещены в библиотеку Qt3Support. В новых приложениях Qt вы должны использовать вместо них QListWidget или его базовый класс QListView. Обзор новых классов представления элементов смотрите в Программирование модель/представление. QListViewКлассы QListView, QListViewItem, QCheckListItem и QListViewItemIterator были переименованы в Q3ListView, Q3ListViewItem, Q3CheckListItem и Q3ListViewItemIterator, соответственно, и перемещены в библиотеку Qt3Support. Новые приложения Qt должны использовать взамен один из четырех класса: QTreeView или QTreeWidget - для древовидных структур; QListWidget или новый класс QListView - для линейных списков. Обзор новых классов представления элементов смотрите в Программирование модель/представление. QLocalFsКласс QLocalFs больше не является частью открытого Qt API. Он был переименован в Q3LocalFs и перемещен в Qt3Support. Вместо этого используйте QDir, QFileInfo или QFile. QMainWindowКласс QMainWindow был перепроектирован в Qt 4 чтобы предоставить более современный внешний вид и поведение, а также большую гибкость. Для отражения этого был изменен API. Старый класс QMainWindow был переименован в Q3MainWindow и перемещен в Qt3Support. За подробностями обращайтесь к документации класса QMainWindow. QMemArray<T>QMemArray<T> был перемещен в Qt3Support. Он был заменен классом QVector<T>. В следующей таблице приведены различия в API между двумя классами.
Замечания:
QMenuBarВ Qt 3 QMenuBar наследовался от QFrame и QMenuData; в Qt 4 он является прямым подклассом QWidget. Приложения, которые предоставляют настраиваемые панели меню, могут получить преимущества возможностей применения стилей, описанные в документе Таблицы стилей Qt. В Qt 4 невозможно добавить виджеты в панель меню. QMenuDataВ Qt 4 класс QMenu предоставляет виджет меню, который можно использовать во всех местах, где в приложении используются меню. В отличие от QMenuData, QMenu спроектирован вокруг концепции действий, предоставляемых классом QAction, взамен используемых в Qt 3 идентификаторов. В Qt 3 можно было вставлять виджеты в меню используя специальную перегрузку QMenuData::insertItem(). В Qt 4.2 и старше, класс QWidgetAction может быть использован для обёртывания виджетов для использования в основанных на действиях API Qt 4. QMessageBoxФункция QMessageBox::iconPixmap() использовалась для возвращения "const QPixmap *". В Qt 4 она возвращает QPixmap. QMimeSourceFactoryQMimeSourceFactory был переименован в Q3MimeSourceFactory и перемещен в библиотеку Qt3Support. Новые приложения Qt должны взамен использовать Систему ресурсов Qt 4. QMovieQMovie API был пересмотрен в Qt 4 чтобы сделать его более совместимым с остальными классами Qt (особенно QImageReader). В таблице ниже приведены изменения.
QMultiLineEditКласс QMultiLineEdit в Qt 3 был вспомогательным подклассом QTextEdit, который предоставлял интерфейс, совместимый с классом Qt 2 QMultiLineEdit. В Qt 4 он называется Q3MultiLineEdit, унаследован от Q3TextEdit, и является частью Qt3Support. Используйте QTextEdit в новом коде. QNetworkProtocolКлассы QNetworkProtocol, QNetworkProtocolFactoryBase, QNetworkProtocolFactory<T> и QNetworkOperation больше не являются частью открытого Qt API. Они были переименованы в Q3NetworkProtocol, Q3NetworkProtocolFactoryBase, Q3NetworkProtocolFactory<T> и Q3NetworkOperation, соответственно, и перемещены в библиотеку Qt3Support. В приложениях Qt 4 вы можете использовать классы подобно QFtp и QNetworkAccessManager прямо для выполнения действий связанных с файлами на удаленном узле. QObjectQObject::children() теперь возвращает QObjectList взамен указателя на QObjectList. Смотрите также примечания к QObjectList ниже. Используйте QObject::findChildren() вместо QObject::queryList(). Например: QList<QWidget *> myWidgets = myParent->findChildren<QWidget *>(); QObject::killTimers() была удалена, поскольку была небезопасна для использования в подклассе. (Обычно подкласс не знает использует ли базовый класс таймеры или нет.) Свойство QObject::name было переименовано в QObject::objectName. QObject::objectTrees() была удалена. Если вы в основном заинтересованы в виджетах, используйте QApplication::allWidgets() или QApplication::topLevelWidgets(). QObjectDictionaryКласс QObjectDictionary является синонимом для QAsciiDict<QMetaObject>. Смотрите раздел в QAsciiDict<T>. QObjectListВ Qt 3 класс QObjectList был псевдонимом (typedef) для QPtrList<QObject>. В Qt 4 он является псевдонимом (typedef) для QList<QObject *>. Смотрите раздел в QPtrList<T>. QPaintDeviceДля переопределения бэкендов рисовальщика предварительно необходимо переопределить виртуальную функцию QPaintDevice::cmd(). Эта функция удалена и должна быть заменена функцией QPaintDevice::paintEngine() и абстрактным классом QPaintEngine. QPaintEngine предоставляет виртуальные функции для всех операций рисования, которые могут выполняться в бэкенде рисовальщика. bitBlt() и copyBlt() теперь являются только функциями совместимости. Вместо этого используйте QPainter::drawPixmap(). QPaintDeviceMetricsВсе использовавшиеся функции, представляемые классом QPaintDeviceMetrics, теперь перемещены в QPaintDevice. Например, если у вас есть код QPaintDeviceMetrics metrics(widget); int deviceDepth = metrics.depth(); вы можете записать его в виде int deviceDepth = widget->depth(); Для совместимости старый класс QPaintDeviceMetrics был переименован в Q3PaintDeviceMetrics и перемещен в Qt3Support. QPainterКласс QPainter подвергся в Qt 4 некоторым изменениям, поскольку изменился способ отрисовки прямоугольников. В Qt 4 результат отрисовки QRect с пером толщиной в 1 пиксел на 1 пиксел шире и на 1 пиксел выше, чем в Qt 3. Для совместимости мы предоставляем класс Q3Painter в Qt3Support, который обеспечивает старую семантику. За подробностями и причинами сделанных изменений обращайтесь к документации Q3Painter. Перечисление QPainter::CoordinateMode было удалено в Qt 4. Все операции отсечения теперь описываются, используя логические координаты и являются предметом операций преобразования. Перечисление QPainter::RasterOP было заменено на QPainter::CompositionMode. QPictureВ Qt 3 QPicture можно было сохранить в формат файла SVG. В Qt 4, поддержка SVG предоставляется модулем QtSvg, который включает в себя классы для вывода на экран содержимого файлов SVG. Если вы хотите сгенерировать файлы SVG, вы можете использовать класс совместимости Q3Picture или введенный в Qt 4.3 класс QSvgGenerator. QPixmapФункция mask() была изменена так, чтобы возвращать ссылку на QBitmap, а не указатель. В результате, больше нет возможности просто проверить на нулевой указатель при определении имеет ли растровое изображение маску. Взамен, вам нужно явно проверить равна ли битовая маска нулю или нет. Например, если у вас есть код if (pixmap.mask()) widget->setMask(*pixmap.mask()); вы можете записать его в виде if (!pixmap.mask().isNull()) widget->setMask(pixmap.mask()); Механизмы QPixmap::setOptimization() и QPixmap::setDefaultOptimization() более недоступны в Qt 4. QPointArrayКласс QPointArray был переименован в QPolygon в Qt 4 и претерпел значительные изменения. В Qt 3 QPointArray наследовался от QMemArray<QPoint>. В Qt 4 QPolygon унаследован от QVector<QPoint>. Все приведенное в разделе в QMemArray<T> также применимо к QPointArray. Библиотека Qt3Support содержит класс Q3PointArray, который унаследован от QPolygon и предоставляет несколько функций, которые имелись в QPointArray, но больше нет в QPolygon. Эти функции включают Q3PointArray::makeArc(), Q3PointArray::makeEllipse() и Q3PointArray::cubicBezier(). Для представления дуг, эллипсов и кривых Безье в Qt 4 мы рекомендуем вам использовать QPainterPath , а не QPolygon. В Qt 4 функции QPolygon::setPoints() и QPolygon::putPoints() возвращают void. Соответствующие функции Qt 3 возвращали bool, указывая был ли изменен размер массива удачно или нет. Теперь это можно проверить проверяя QPolygon::size() после вызова. QPopupMenuВ большинстве случаев QPopupMenu заменен на QMenu в Qt 4. Для совместимости со старыми приложениями, Q3PopupMenu предоставляет старый API и возможности, которые специфичны для всплывающих меню. Обратите внимание на то, что при использовании Q3PopupMenu действия меню должны быть объектами Q3Action. В Qt 3 было общей практикой добавлять пункты во всплывающие меню, используя функцию insertItem(), сохраняющую идентификаторы для последующего использования; например, для динамического изменения элементов меню. В Qt 4 пункты меню полностью представляются действиями для согласованности с другими компонентами пользовательского интерфейса, например, кнопок панели инструментов. Создавайте новые меню с помощью класса QMenu, а для вставки новых пунктов используйте перегруженные функции QMenu::addAction(). Если вам нужно управлять набором действий, созданных для конкретного меню, мы советуем вам создать QActionGroup и добавить их в него. Предоставленные Примеры главного окна показывают, как использовать систему действий Qt для создания меню, панелей инструментов и других общих распространенных элементов пользовательского интерфейса. QPrinterКласс QPrinter теперь ожидает настройку печати из QPrintDialog. QProcessКласс QProcess подвергся значительному улучшению в Qt 4. Теперь наследуется от QIODevice, что делает возможным сочетание QProcess с QTextStream или QDataStream. Старый класс QProcess был переименован в Q3Process и перемещен в библиотеку Qt3Support. QProgressBarAPI класса QProgressBar было существенно улучшено в Qt 4. Старый API QProgressBar доступен как Q3ProgressBar в библиотеке Qt3Support. QProgressDialogAPI класса QProgressDialog был существенно улучшено в Qt 4. Старый API QProgressDialog доступен как Q3ProgressDialog в библиотеке Qt3Support. Смотрите в Свойствах список свойств QProgressDialog в Qt 3, которые изменились в Qt 4. QPtrCollection<T>Абстрактный базовый класс QPtrCollection<T> был переименован в Q3PtrCollection<T> и перемещен в библиотеку Qt3Support. В Qt 4 прямого эквивалента нет. Список контейнеров Qt 4 смотрите в Контейнерных классах. QPtrDict<T>QPtrDict<T> и QPtrDictIterator<T> были переименованы в Q3PtrDict<T> и Q3PtrDictIterator<T>, соответственно, и перемещены в библиотеку Qt3Support. Они заменены более современными классами QHash<Key, T> и QMultiHash<Key, T>, соответственно, и их соответствующими классами-итераторами. При портировании на Qt 4 старого кода, который использует Q3PtrDict<T>, имеется четыре класса, которые вы можете использовать:
(Естественно, вы можете использовать другие типы помимо void * для типа ключа, например QWidget *.) Для портирования Q3PtrDict<T> на Qt 4, читайте раздел в QDict<T>, заменяя в уме void * на QString. QPtrList<T>QPtrList<T>, QPtrListIterator<T> и QPtrListStdIterator<T> были перемещены в библиотеку Qt3Support. Их заменили более современные классы QList и QLinkedList и связанные с ними классы-итераторы. При портировании на Qt 4, вы можете выбрать использование QList<T> или QLinkedList<T> в качестве альтернативы QValueList<T>. QList<T> имеет API, основанный на индексах, и представляет очень быстрый произвольный доступ (QList::operator[]), тогда как QLinkedList<T> имеет API, основанный на итераторах. В следующей таблице приведены различия API QPtrList<T> и QList<T *>:
Замечания:
Если вы используете возможность QPtrList'а - автоудаление (вызывая QPtrList::setAutoDelete(true)), вам нужно сделать немного больше работы. У вас есть два варианта: Вы либо сами вызываете delete всякий раз, когда удаляете элемент из контейнера, либо вы используете QList<T> вместо QList<T *> (т.е. сохраняете значения непосредственно взамен указателей на значения). Здесь мы увидим когда вызвать delete. В следующей таблице приведены стили, которые вам нужно знать, если вы хотите сами вызывать delete.
Имейте в виду, что деструктор QPtrList'а автоматически вызывает clear(). Если у вас в пользовательском классе имеется член данных QPtrList и вы используете возможность автоудаления, то чтобы избежать утечки памяти вам будет нужно вызывать из деструктора вашего класса delete для всех элементов контейнера. QPtrList имеет концепцию "текущего элемента", которая может быть использована для обхода списка без использования итератора. При портировании на Qt 4 вы можете использовать взамен класс в стиле Java QListIterator<T *> (или QMutableListIterator<T *>). В следующей таблице приведены различия в API.
Имейте в виду, что QListIterator имеет другой способ перебора элементов, чем QPtrList. Типичный цикл с QPtrList выглядит примерно так: QPtrList<QWidget> list; ... while (list.current() != 0) { do_something(list.current()); list.next(); } Вот эквивалентный цикл с QListIterator: QList<QWidget *> list; ... QListIterator<QWidget *> i(list); while (i.hasNext()) do_something(i.next()); В заключение, QPtrListIterator<T> также должен быть портирован. Имеется не менее четырех классов-итераторов, которые могут использоваться в качестве замены: QList::const_iterator, QList::iterator, QListIterator и QMutableListIterator. Проще всего использовать при портировании класс QMutableListIterator<T *> (если вы вносите изменения в список посредством итератора) или QListIterator<T *> (если не вносите изменений). В следующей таблице приведены различия в API.
Вновь, имейте ввиду, что QListIterator имеет другой способ перебора элементов, чем QPtrList. Типичный цикл с QPtrList выглядит примерно так: QPtrList<QWidget> list; ... QPtrListIterator<QWidget> i; while (i.current() != 0) { do_something(i.current()); i.next(); } Вот эквивалентный цикл с QListIterator: QList<QWidget *> list; ... QListIterator<QWidget *> i(list); while (i.hasNext()) do_something(i.next()); В заключение, QPtrListStdIterator<T> должен также быть портирован. Это легко сделать, поскольку QList также предоставляет итераторы в стиле STL (QList::iterator и QList::const_iterator). QPtrQueue<T>QPtrQueue был перенесен в библиотеку Qt3Support. Его заменил более современный класс QQueue. В следующей таблице приведены различия между QPtrQueue<T> и QQueue<T *>:
Если вы используете возможность QPtrQueue'а автоудаления (вызывая QPtrQueue::setAutoDelete(true)), вам нужно сделать немного больше работы. У вас есть два варианта: Вы либо сами вызываете delete всякий раз, когда удаляете элемент из контейнера, либо вы используете QQueue<T> вместо QQueue<T *> (т.е. сохраняете значения непосредственно взамен указателей на значения). Здесь мы увидим когда вызвать delete.
QPtrStack<T>QPtrStack был перемещен в библиотеку Qt3Support. Его заменил более современный класс QStack. В следующей таблице приведены различия между QPtrStack<T> и QStack<T *>:
Если вы используете возможность QPtrStack'а - автоудаление (вызывая QPtrStack::setAutoDelete(true)), вам нужно сделать немного больше работы. У вас есть два варианта: Вы либо сами вызываете delete всякий раз, когда удаляете элемент из контейнера, либо вы используете QStack<T> вместо QStack<T *> (т.е. сохраняете значения непосредственно взамен указателей на значения). Здесь мы увидим когда вызвать delete.
QPtrVector<T>QPtrVector<T> был перемещен в Qt3Support. Его заменил более современный класс QVector. При портировании на Qt 4 вы можете использовать QVector<T *> в качестве альтернативы для QPtrVector<T>. API QPtrVector<T> и QVector<T *> весьма похожи. Основной проблемой является то, что QPtrVector поддерживает автоудаление, тогда как QVector - нет. В следующей таблице приведены различия в API между двумя классами:
Замечания:
Если вы используете возможность QVector'а - автоудаление (вызывая QVector::setAutoDelete(true)), вам нужно сделать немного больше работы. У вас есть два варианта: Вы либо сами вызываете delete всякий раз, когда удаляете элемент из контейнера, либо вы используете QVector<T> вместо QVector<T *> (т.е. сохраняете значения непосредственно взамен указателей на значения). Здесь мы увидим когда вызвать delete. В следующей таблице приведены стили, которые вам нужно знать, если вы хотите сами вызывать delete.
Имейте в виду, что деструктор QPtrVector'а автоматически вызывает clear(). Если у вас в пользовательском классе имеется член данных QPtrVector и вы используете возможность автоудаления, то чтобы избежать утечки памяти вам будет нужно вызывать из деструктора вашего класса delete для всех элементов контейнера. QPushButtonСмотрите в Свойствах список свойств QPushButton в Qt 3, которые изменились в Qt 4. QRangeControlВ Qt 3 разнообразные виджеты "регулируемого диапазона" (QDial, QScrollBar, QSlider и QSpin) наследовались и от QWidget и от QRangeControl. В Qt 4 QRangeControl был заменен новыми классами QAbstractSlider и QAbstractSpinBox, которые унаследованы от QWidget и предоставляют аналогичную функциональность. Кроме устранения ненужного множественного наследования, новый дизайн позволяет QAbstractSlider предоставлять сигналы, слоты и свойства. Старый класс QRangeControl был переименован в Q3RangeControl и перемещен в библиотеку Qt3Support, вместе с (недокументированным) классом QSpinWidget. Если вы используете QRangeControl в качестве базового класса с своих приложениях, взамен вы можете переключиться на использование QAbstractSlider или QAbstractSpinBox. Например, если у вас есть код class VolumeControl : public QWidget, public QRangeControl { ... protected: void valueChange() { update(); emit valueChanged(value()); } void rangeChange() { update(); } void stepChange() { update(); } }; вы можете записать его в виде class VolumeControl : public QAbstractSlider { ... protected: void sliderChange(SliderChange change) { update(); if (change == SliderValueChange) emit valueChanged(value()); } }; QRegExpФункции search() и searchRev() были переименованы в indexIn() и lastIndexIn(), соответственно. QRegionВ Qt 4 был сделаны следующие изменения в QRegion:
QScrollBarСмотрите в Свойствах список свойств QScrollBar в Qt 3, которые изменились в Qt 4. QScrollViewКласс QScrollView был переименован в Q3ScrollView и перемещен в библиотеку Qt3Support. Его заменили классы QAbstractScrollArea и QScrollArea. Обратите внимание на то, что Qt 4 использует в основном функцию QScrollArea::widget() там, где Qt 3 использовала QScrollView::viewport(). Основной причиной этого является то, что больше невозможно рисовать непосредственно на прокручиваемой области. Функция QScrollArea::widget() возвращает виджет, установленный на прокручиваемую область. QScrollView был спроектирован для обхода 16-разрядного ограничения на координаты виджета, встречаемого в большинстве оконных систем. В Qt 4 это делается прозрачно для всех виджетов, поэтому больше нет необходимости в подобной функциональности в QScrollView. По этой причине новые классы QAbstractScrollArea и QScrollArea более легкие и сосредоточены на обработке полос прокрутки. QServerSocketКласс QServerSocket был переименован в Q3ServerSocket и перемещен в библиотеку Qt3Support. В Qt 4 его заменил класс QTcpServer. С помощью Q3ServerSocket, соединения принимаются переопределенной виртуальной функцией (Q3ServerSocket::newConnection()). С помощью QTcpServer, с другой стороны, вам не нужно создавать подклассы. Взамен просто присоедините к сигналу QTcpServer::newConnection(). QSettingsКласс QSettings был переписан чтобы сделать его более устойчивым к ошибкам и соблюдающим существующие стандарты (например, формат файла INI). API также был сильно переработан. Старый API по-прежнему предоставляется при включенной поддержке Qt 3. Поскольку между Qt 3 и Qt 4 форма и расположение настроек изменились, версия Qt 4 вашего приложения не распознает настройки, записанные с использованием Qt 3. QSharedКласс QShared устарел с появлением более мощных QSharedData и QSharedDataPointer как средства создания пользовательских классов с неявным разделением данных. Он был переименован в Q3Shared и перемещен в библиотеку Qt3Support. Легким способом портирования на Qt 4 является включение этого класса в ваш проект и используйте его вместо QShared: struct Shared { Shared() : count(1) {} void ref() { ++count; } bool deref() { return !--count; } uint count; }; Если возможно, мы рекомендуем вам использовать взамен QSharedData и QSharedDataPointer. Они предоставляют потокобезопасный подсчет ссылок и скрытно обрабатывают весь подсчет ссылок, устраняя риски забыть инкрементировать или декрементировать счетчик ссылок. QSignalКласс QSignal был переименован в Q3Signal и перемещен в библиотеку Qt3Support. Предпочтительный подход заключается в создании вашего собственного подкласса QObject с сигналом, который имеет желаемую сигнатуру. В качестве альтернативы вы можете вызвать QMetaObject::invokeMethod(), если вы хотите вызвать слот. QSimpleRichTextQSimpleRichText устарел с появлением QTextDocument. Он был переименован в Q3SimpleRichText и перемещен в библиотеку Qt3Support. Раньше вы должны были делать следующее с помощью Q3SimpleRichText: // Объявляем объект QSimpleRichText richText(text, font); // Устанавливаем ширину абзаца равной w richText.setWidth(w); // Или устанавливаем приемлемый размер по умолчанию richText.adjustSize(); // Запрашиваем используемый размер int width = richText.widthUsed(); int height = richText.height(); // Отрисовываем richText.draw(painter, x, y, clipRect, colorGroup); Однако, с QTextDocument вы используете вместо этого следующий код: // Объявляем объект QTextDocument doc; // Если текст является форматированным текстом, то используйте setHtml() doc.setHtml(text); // В противном случае, используйте setPlainText() doc.setPlainText(text); // Устанавливаем ширину абзаца текста равной w doc.setTextWidth(w); // Запрашиваем используемый размер int width = doc.idealWidth(); int height = doc.size().height(); // Отрисовываем painter.translate(x, y); doc.drawContents(painter, clipRect); // Если у вас есть палитра/цветовая группа, то вы можете отрисовывать, используя низкоуровневые функции: QAbstractTextDocumentLayout::PaintContext context; context.palette = myPalette; doc.documentLayout()->draw(painter, context); Обзор классов форматированного текста Qt 4 смотрите в Обработке форматированного текста. QSliderФункции QSlider::sliderStart() и QSlider::sliderRect() были удалены. Прямоугольник ползунка можно теперь получить используя нижеприведенный фрагмент кода: QSlider *slider; slider->style()->subControlRect(CC_Slider, sliderOption, SC_SliderHandle, slider); В дополнение, направление вертикального QSlider'а изменилось, т.е. минимум теперь внизу, а максимум - вверху. Вы можете использовать свойство QAbstractSlider::invertedAppearance для управления этим поведением. Смотрите в Свойствах список свойств QSlider в Qt 3, которые изменились в Qt 4. QSocketКласс QSocket был переименован в Q3Socket и перемещен в библиотеку Qt3Support. В Qt 4 он был заменен классом QTcpSocket, который унаследовал от QAbstractSocket большую часть его функциональности. QSocketDeviceКласс QSocketDevice был переименован в Q3SocketDevice и перемещен в библиотеку Qt3Support. В Qt 4 для Q3SocketDevice прямого эквивалента нет:
QSortedListКласс QSortedList<T> устарел с Qt 3.0. В Qt 4 он был перемещен в библиотеку Qt3Support. В новом коде мы рекомендуем вам использовать взамен QList<T> и использовать qSort() для сортировки элементов. QSplitterФункция setResizeMode() была перенесена в Qt3Support. Установите коэффициент растяжения в политике размеров виджета чтобы получить эквивалентную функциональность. Устаревшая функция drawSplitter() была удалена. Используйте QStyle::drawPrimitive() чтобы получить аналогичную функциональность. QSpinBoxСмотрите в Свойствах список свойств QSpinBox в Qt 3, которые изменились в Qt 4. QSqlCursorКласс QSqlCursor был переименован в Q3SqlCursor и перемещен в библиотеку Qt3Support. В Qt 4 вы можете использовать QSqlQuery, QSqlQueryModel или QSqlTableModel, в зависимости от того нужен ли вам низкоуровневый или высокоуровневый интерфейс для доступа к базам данных. Обзор новых классов SQL смотрите в Модуле QtSql. QSqlDatabaseQSqlDatabase - теперь интеллектуальный (smart) указатель, который передавался по значению. Просто замените все указатели QSqlDatabase на объекты QSqlDatabase. QSqlEditorFactoryКласс QSqlEditorFactory был переименован в Q3SqlEditorFactory и перемещен в Qt3Support. Обзор новых классов SQL смотрите в Модуле QtSql. QSqlErrorПеречисление Type было переименовано в ErrorType, Значения были также переименованы:
QSqlFieldInfoКласс QSqlFieldInfo был перемещен в Qt3Support. Его функциональность теперь предоставляется классом QSqlField. Обзор новых классов SQL смотрите в Модуле QtSql. QSqlFormКласс QSqlForm был переименован в Q3SqlForm и перемещен в библиотеку Qt3Support. Обзор новых классов SQL смотрите в Модуле QtSql. QSqlPropertyMapКласс QSqlPropertyMap был переименован в Q3SqlPropertyMap и перемещен в библиотеку Qt3Support. Обзор новых классов SQL смотрите в Модуле QtSql. QSqlQueryQSqlQuery::prev() была переименована в QSqlQuery::previous(). QSqlQuery::prev() осталась, но она только вызывает previous(). QSqlQuery больше не имеет каких-либо виртуальных методов, т.е., exec(), value(), seek(), next(), prev(), first(), last() и деструктор больше не являются виртуальными. QSqlRecordQSqlRecord теперь ведет себя как вектор, QSqlRecord::insert() фактически будет вставлять новое поле вместо замены существующего. QSqlRecordInfoКласс QSqlRecordInfo был перемещен в Qt3Support. Его функциональность теперь предоставляется классом QSqlRecord. Обзор новых классов SQL смотрите в Модуле QtSql. QSqlSelectCursorКласс QSqlSelectCursor был переименован в Q3SqlSelectCursor и перемещен в библиотеку Qt3Support. Обзор новых классов SQL смотрите в Модуле QtSql. QStoredDragКласс QStoredDrag был переименован в Q3StoredDrag и перемещен в библиотеку Qt3Support. В Qt 4 используйте взамен QMimeData и вызовите QMimeData::setData() для установки данных. Смотрите Портирование на Qt 4 - Перетаскивание для сравнения API перетаскивания в Qt 3 и Qt 4. QStr(I)ListВспомогательные классы QStrList и QStrIList устарели начиная с Qt 2.0. В Qt 4 они были перемещены в библиотеку Qt3Support. Если вы использовали какой-либо из них, мы рекомендуем вам использовать взамен QStringList или QList<QByteArray>. QStr(I)VecВспомогательные классы QStrVec и QStrIVec устарели начиная с Qt 2.0. В Qt 4 они были перемещены в Qt3Support. Если вы использовали какой-либо из них, мы рекомендуем вам использовать взамен QStringList или QList<QByteArray>. QStringВот основные известные проблемы, о которых нужно знать при портировании QString на Qt 4:
QStringListQStringList теперь наследуется от QList<QString> и больше не может быть конвертирован в QValueList<QString>. Так как QValueList унаследован от QList приведение типа будет работать как ожидалось. Это изменение подразумевает некоторые несовместимости в API для QStringList. Например, at() возвращает строку, а не итератор. За подробностями обращайтесь к разделу в QValueList. Статическая функция QStringList::split() для разделения строк на списки меньших строк была заменена на QString::split(), которая возвращает QStringList. QStyleAPI класса QStyle усовершенствован и улучшен. Большая часть информации о том, почему были сделаны эти изменения описана в обзоре QStyle. Так как QStyle используется в основном для внутренних нужд виджетами Qt и стилями, а также поскольку он не является необходимым для хорошего функционирования приложения, способов совместимости нет. Это означает, что мы изменили многие перечисления и функции, а также инструмент портирования qt3to4 не будет вносить большие изменения в коде qstyle. Чтобы облегчить боль, мы перечислим здесь некоторые из наиболее важны изменений. QStyleOption занял более существенную роль и больше не является необязательным аргументом, пожалуйста, для получения дополнительной информации смотрите документацию QStyleOption. QStyle::StyleFlags были переименованы в QStyle::StateFlags и теперь предваряются префиксом State_ вместо Style_, кроме того флаг Style_ButtonDefault был перемещен в QStyleOptionButton. Перечисление QStyle::PrimitiveElement было подвергнуто обширным изменениям. Некоторые из перечисления были перемещены в QStyle::ControlElement, некоторые были удалены и все были переименованы. Это переименование не выполняется инструментом портирования qt3to4, поэтому вы должны выполнить его сами. В таблице ниже показано, как теперь выглядят вещи. Функции QStyle::drawControlMask() и QStyle::drawComplexControlMask() были удалены. Их заменили подсказка стиля. Перегрузки QStyle::drawItem(), которые получали и растровое изображение и строку, были удалены. Используйте непосредственно QStyle::drawItemText() и QStyle::drawItemPixmap(). Перегрузка QStyle::itemRect(), которая получает и растровое изображение и стоку, также удалена, используйте взамен или QStyle::itemTextRect() или QStyle::itemPixmapRect(). QStyleSheetКлассы QStyleSheet и QStyleSheetItem были переименованы в Q3StyleSheet и Q3StyleSheetItem, соответственно, и были перемещены в библиотеку Qt3Support. Обзор классов форматированного текста Qt 4 смотрите в Обработке форматированного текста, а описание поддержки CSS-подобных таблиц стилей в Qt 4.2 и старше - в Таблицах стилей Qt. QSyntaxHighlighterКласс QSyntaxHighlighter из Qt 3 был переименован в Q3SyntaxHighlighter и перемещен в библиотеку Qt3Support. Начиная с Qt 4.1 его заменил новый класс QSyntaxHighlighter, базирующийся на новом механизме форматированного текста Qt 4. QTabBarСмотрите в Свойствах список свойств QTabBar в Qt 3, которые изменились в Qt 4. QTabDialogКласс QTabDialog больше не является частью открытого Qt API. Он был переименован в Q3TabDialog и перемещен в Qt3Support. В приложениях Qt 4 вы можете легко получить тот же результат сочетая QTabWidget c QDialog и предоставив сами объекты QPushButton. Смотрите также пример dialogs/tabdialog, который показывает как реализовать диалоги со вкладками в Qt 4. QTabWidgetСмотрите в Свойствах список свойств QTabWidget в Qt 3, которые изменились в Qt 4. QTableКлассы QTable, QTableItem, QComboTableItem, QCheckTableItem и QTableSelection были переименованы в Q3Table, Q3TableItem, Q3ComboTableItem, Q3CheckTableItem и Q3TableSelection, соответственно, и перемещены в библиотеку Qt3Support. Новые приложения Qt должны использовать взамен новый класс QTableWidget или QTableView. Некоторые из этих классов ведут себя по-другому по сравнению с использование обработки указателей NULL. Например, Q3TableItem::setPixmap() больше не принимает NULL или 0 чтобы указать, что элемент должен содержать нулевое растровое изображение; в этом случае нулевое растровое изображение должно быть создано и передано явно в функцию. Обзор новых классов представления элементов смотрите в Программирование модель/представление. QTextCodecФункции loadCharmap() и loadCharmapFromFile() больше не доступны в Qt 4. Вам нужно создать ваш собственный кодек, если вы хотите создать кодек основанный на описании таблицы кодов символов POSIX2. QTextDragКласс QTextDrag был переименован в Q3TextDrag и перемещен в библиотеку Qt3Support. В Qt 4 используйте взамен QMimeData и вызовите QMimeData::setText() для установки данных. Смотрите Портирование на Qt 4 - Перетаскивание для сравнения API перетаскивания в Qt 3 и Qt 4. QTextEditСтарые классы QTextEdit и QTextBrowser были переименованы в Q3TextEdit и Q3TextBrowser, соответственно, и перемещены в Qt3Support. Новые классы QTextEdit и QTextBrowser имеют немного другой API. Функция QTextEdit::setWrapPolicy() была переименована в setWordWrapMode(), а функция QTextEdit::setWrapColumnOrWidth() была переименована в setLineWrapColumnOrWidth(). Функции Q3TextEdit::setWrapPolicy() и Q3TextEdit::setWrapColumnOrWidth() предоставляют эту функциональность в классе Q3TextEdit. Обзор классов форматированного текста Qt 4 смотрите в Обработке форматированного текста. QTextIStreamВспомогательный класс QTextIStream больше не предоставляется в Qt 4. Используйте вместо нее непосредственно QTextStream. QTextOStreamВспомогательный класс QTextOStream больше не предоставляется в Qt 4. Используйте вместо нее непосредственно QTextStream. QTextOStreamIteratorНедокументированный класс QTextOStreamIterator был удален из библиотеки Qt. Если он необходим в вашем приложении, просто скопируйте исходный код из заголовочного файла <qtl.h> Qt 3. QTextStreamВ QTextStream некоторому улучшению подвергся API и реализация, а некоторые изменения повлияли на поведение QTextStream'а:
Обратите внимание на то, что в Qt 4 при использовании QTextStream на QFile, вызов QIODevice::reset() на QFile не будет иметь ожидаемого результата, поскольку QTextStream теперь буферизует файл. Вместо этого используйте функцию QTextStream::seek(). QTextViewКласс QTextView был переименован в Q3TextView и перемещен в библиотеку Qt3Support. QTimeEditКласс QTimeEdit в Qt 4 является вспомогательным классом, базирующимся на QDateTimeEdit. Старый класс был переименован в Q3TimeEdit и перемещен в библиотеку Qt3Support. Смотрите в Виртуальных функциях список виртуальных функций-членов QTimeEdit в Qt 3, которые больше не являются виртуальными в Qt 4. QTimerWindows ограничивает точность таймеров, но начиная с Qt 4, мы эмулируем точное временное разрешение. В Windows XP мы используем API мультимедийного таймера, который дает разрешение в 1 миллисекунду для QTimer. Обратите внимание на то, что Windows 2000 меньшее временное разрешение, и что код, зависящий от базовой системы ограничения таймера, не сталкивается с такими ограничениями при использовании Qt 4 (например, установка интервала в 0 миллисекунд приведет в Qt к завладению всем процессорным временем когда не нужно обрабатывать никаких событий ГПИ). QToolBarСтарый класс QToolBar, который работал со старыми классами QMainWindow и QDockArea и унаследован от QDockWindow, был переименован в Q3ToolBar и перемещен в Qt3Support. Обратите внимание на то, что, когда используется Q3ToolBar, действия панели инструментов должны быть объектами Q3Action. В новых приложениях используйте новый класс QToolBar. Замечание: Свойство Q3ToolBar'а, horizontallyStretchable, может быть достигнуто в QToolBar с помощью политик размера. QToolButtonСмотрите в Свойствах список свойств QToolButton в Qt 3, которые изменились в Qt 4. Обратите внимание на то, что многие свойства, которые могут быть предварительно установлены в конструкторе должны теперь устанавливаться раздельно. QToolTipФункции QToolTip::setGloballyEnabled() больше нет. Всплывающие подсказки могут быть отключены установкой фильтра событий на qApp (уникальный объект QApplication) для блокирования событий типа QEvent::ToolTip. QUriDragКласс QUriDrag был переименован в Q3UriDrag и перемещен в библиотеку Qt3Support. В Qt 4 используйте взамен QMimeData и вызовите QMimeData::setUrl() для установки URL. Смотрите Портирование на Qt 4 - Перетаскивание для сравнения API перетаскивания в Qt 3 и Qt 4. QUrlКласс QUrl был переписан с нуля в Qt 4 чтобы быть более соответствующим стандарту. Старый класс QUrl был переименован в Q3Url и перемещен в библиотеку Qt3Support. Новый класс QUrl предоставляет исчерпывающий список функций совместимости для облегчения портирования с Q3Url на QUrl. Новые функции требуют изменить ваш код:
QUrlOperatorКласс QUrlOperator больше не является частью открытого Qt API. Он был переименован в Q3UrlOperator и перемещен в Qt3Support. Начиная с Qt 4.4 Network Access API предоставляет подмножество возможностей, предоставляемых QUrlOperator, которые предназначены в основном для использования с приложениями, которые используют протоколы HTTP и FTP. Подробности смотрите в документации к QNetworkRequest, QNetworkReply и QNetworkAccessManager. QValueList<T>Класс QValueList<T> был заменен QList<T> и QLinkedList<T> в Qt 4. В качестве помощи при портировании старых приложений Qt, библиотека Qt3Support содержит класс QValueList<T>, реализованный на основе нового класса QLinkedList<T>. Аналогичным образом, он содержит классы QValueListIterator<T> и QValueListConstIterator<T>, реализованные на основе QLinkedList<T>::iterator и QLinkedList<T>::const_iterator. При портировании на Qt 4, вы можете выбрать использование QList<T> или QLinkedList<T> в качестве альтернативы QValueList<T>. QList<T> имеет API, основанный на индексах, и представляет очень быстрый произвольный доступ (QList::operator[]), тогда как QLinkedList<T> имеет API, основанный на итераторах. Вот список проблемных функций:
QValueVector<T>Класс QValueVector<T> был заменен классом QVector<T> в Qt 4. В качестве помощи при портировании старых приложений Qt, библиотека Qt3Support содержит класс Q3ValueVector<T>, реализованный на основе нового класса QVector<T>. При портировании с QValueVector<T> на QVector<T>, вы можете столкнуться со следующими несовместимостями:
Обзор контейнерных классов Qt 4 смотрите в Контейнерных классах. QVariantНекоторые изменения в остальной части библиотеки Qt имеют последствия для QVariant:
Также конструктор QVariant(bool, int) был заменен QVariant(bool). Старый код, наподобие QVariant(true, 0), должен быть заменен на QVariant(true); в противном случае, может быть случайно вызвана перегрузка QVariant(int, void *). Многие из вспомогательных функций QVariant'а в Qt 3, такие как toColor() и toKeySequence(), были удалены чтобы позволить QVariant быть частью модуля QtCore. QVariant по-прежнему способен хранить значения этих типов. Типы, которые не поддерживаются какими-либо конструкторами QVariant, могут быть сохранены как универсальные типы с помощью функции QVariant::fromValue(). Типы с неподходящей вспомогательной функцией для распаковки можно получить с помощью функции QVariant::value() или передав непосредственно классам, в которых реализован оператор QVariant().
Смотрите в перечислении QVariant::Type список типов, поддерживаемых QVariant. QVBoxКласс QVBox теперь доступен в Qt 4 только как Q3VBox. Вы можете добиться такого же результата, что и с QVBox создав QWidget с вертикальной компоновкой: Например, если у вас есть код QVBox *vbox = new QVBox; QPushButton *child1 = new QPushButton(vbox); QPushButton *child2 = new QPushButton(vbox); вы можете записать его в виде QWidget *vbox = new QWidget; QPushButton *child1 = new QPushButton; QPushButton *child2 = new QPushButton; QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(child1); layout->addWidget(child2); vbox->setLayout(layout); Обратите внимание на то, что дочерние виджеты автоматически не размещаются в компоновке виджета; вам нужно вручную добавить каждый виджет в QVBoxLayout. QVGroupBoxКласс QVGroupBox был переименован в Q3VGroupBox и перемещен в библиотеку Qt3Support. Qt 4 не предоставляет конкретного класса замены для QVBoxLayout поскольку QGroupBox спроектирован виджетом обобщенного контейнера. В результате, вам нужно обеспечить вашу собственную компоновку для любых дочерних виджетов. Для получения дополнительной информации о портировании кода, который использует групповые рамки, смотрите #QGroupBox. QWhatsThisКласс QWhatsThis был перепроектирован в Qt 4. Старый класс QWhatsThis доступен как Q3WhatsThis в Qt3Support. QWidgetОтрисовка фона виджета была значительно улучшена, поддерживая обновления без мерцания и делая возможным получение полупрозрачных виджетов. Это приводит к тому, что следующие функции обработки фона устарели:
Код примера того, как в Qt 4 получить аналогичное поведение, ранее выполняемое некоторыми вышеприведенными функциями, можно найти на странице Поддерживаемые члены Qt 3 класса QWidget. Виджет теперь получает события изменения в своем обработчике QWidget::changeEvent(). Это делает следующие измененные виртуальные обработчики устаревшими:
Следующие функции были слотами, но теперь ими не являются:
Следующие функции были неправильно помечены как виртуальные:
Внутренняя функция clearWState() была удалена. Вместо этого используйте QWidget::setAttribute(). setWFlags() была переименована QWidget::setWindowFlags(). clearWFlags() не имеет прямой замены. Вы можете использовать QWidget::setAttribute() взамен. Например, setAttribute(..., false) для очистки атрибута. Дополнительная информация доступна здесь. testWFlags() была переименована в testAttribute(). Смотрите в Свойствах список свойств QWidget в Qt 3, которые изменились в Qt 4. QWidgetFactoryКласс QWidgetFactory был заменен классом QFormBuilder в Qt 4. QWidgetIntDictКласс QWidgetIntDict был синонимом для QIntDict<QWidget>. В Qt 4 он больше не доступен. Если вы скомпоновали вместе с Qt3Support, вы можете использовать взамен Q3IntDict<QWidget>; в противном случае, смотрите раздел в QDict<T>. QWidgetListВ Qt 3 класс QWidgetList был псевдонимом (typedef) для QPtrList<QWidget>. В Qt 4 он является псевдонимом (typedef) для QList<QWidget *>. Смотрите раздел в QPtrList<T>. QWidgetPluginКласс QWidgetPlugin более не доступен в Qt 4. Чтобы создать пользовательские подключаемые модули виджета, создайте подкласс QDesignerCustomWidgetInterface для предоставления информации о пользовательском виджете, и собрать подключаемый модуль способом, описанным в примере Пользовательский подключаемый модуль виджета. QWidgetStackКласс QWidgetStack больше не является частью открытого Qt API. Он был переименован в Q3WidgetStack и перемещен в Qt3Support. В приложениях Qt 4 вы можете использовать вместо него QStackedWidget чтобы получить такие же результаты. QWizardКласс QWizard был перепроектирован в Qt 4.3. За подробностями обращайтесь к Примеру "Trivial Wizard", Примеру "License Wizard" и Примеру "Class Wizard". QWorkspaceКласс QWorkspace в Qt 4 требует явного добавления окон MDI с помощью QWorkspace::addWindow(). |
Попытка перевода Qt документации. Если есть желание присоединиться, или если есть замечания или пожелания, то заходите на форум: Перевод Qt документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |