[Предыдущая: Руководства по портированию] [Содержание] [Следующая: Переход на Qt 4 - виртуальные функции] Портирование на Qt 4
|
Функция в Qt 3 | Функция в Qt 4 |
---|---|
T *qt_cast<T *>(QObject *) | T *qobject_cast<T *>(QObject *) |
T qgraphicsitem_cast<T>(QGraphicsItem *) | |
T qstyleoption_cast<T>(QStyleOption *) | |
T qvariant_cast<T>(const QVariant &) | |
T qdbus_cast(const QDBusArgument &) |
В таблице ниже перечислены классы, которые были переименованы в Qt 4. Если вы компилируете свои приложения с определенным макросом QT3_SUPPORT, старые имена будут доступны.
Всякий раз когда вы встречаете имя в левой части, вы можете безопасно заменить его в вашей программе на эквивалент Qt 4. Инструмент qt3to4 выполнит преобразование автоматически.
Имя класса в Qt 3 | Имя класса в Qt 4 |
---|---|
QIconSet | QIcon |
QWMatrix | QMatrix |
QGuardedPtr | QPointer |
В таблице ниже перечислены перечисления и псевдонимы типов (typedefs), которые были переименованы в Qt 4. Если вы компилируете свои приложения с определенным макросом QT3_SUPPORT, старые имена будут доступны.
Всякий раз когда вы встречаете имя в левой части, вы можете безопасно заменить его в вашей программе на эквивалент Qt 4. Инструмент qt3to4 выполнит преобразование автоматически.
Имя типа в Qt 3 | Имя типа в Qt 4 |
---|---|
QApplication::ColorMode | QApplication::ColorSpec |
QButton::ToggleState | QCheckBox::ToggleState |
QCursorShape | Qt::CursorShape |
QFile::FilterSpec | QFile::Filters |
QFile::PermissionSpec | QFile::Permission |
QFile::SortSpec | QFile::SortFlags |
QFile::Status | QFile::Error |
QFileInfo::PermissionSpec | QFile::Permission |
QGrid::Direction | Qt::Orientation |
QGridWidget::Direction | Qt::Orientation |
QIODevice::Offset | qlonglong |
QImage::ScaleMode | Qt::AspectRatioMode |
QSize::ScaleMode | Qt::AspectRatioMode |
QSocket::Error | Q3Socket::Error |
QSocket::State | Q3Socket::State |
QStyle::SCFlags | QStyle::SubControls |
QStyle::SFlags | QStyle::State |
QTS | QTextStream |
QUrlDrag | QUriDrag |
QWidget::FocusPolicy | Qt::FocusPolicy |
Q_LLONG | qlonglong |
Q_ULLONG | qulonglong |
Qt::Dock | Qt::ToolBarDock |
Qt::MacintoshVersion | QSysInfo::MacVersion |
Qt::TextFlags | Qt::TextFlag |
Qt::WindowsVersion | QSysInfo::WinVersion |
В таблице ниже перечислены перечисления, которые были переименованы в Qt 4. Если вы компилируете свои приложения с определенным макросом QT3_SUPPORT, старые имена будут доступны.
Всякий раз когда вы встречаете имя в левой части, вы можете безопасно заменить его в вашей программе на эквивалент Qt 4. Инструмент qt3to4 выполнит преобразование автоматически.
Кроме того, следующие флаги окна были либо заменены атрибутами виджета или устарели:
Тип в Qt 3 | Эквивалент в Qt 4 |
---|---|
Qt::WDestructiveClose | Вместо этого используйте QWidget::setAttribute(Qt::WA_DeleteOnClose). |
Qt::WStaticContents | Вместо этого используйте QWidget::setAttribute(Qt::WA_StaticContents). |
Qt::WNorthWestGravity | |
Qt::WNoAutoErase | Вместо этого используйте QWidget::setAttribute(Qt::WA_NoBackground). |
Qt::WResizeNoErase | |
Qt::WRepaintNoErase | |
Qt::WPaintClever | Не нужны в Qt 4. |
Qt::WMacNoSheet | Не нужны в Qt 4. |
В Qt 4.1 флаги виджета, использовавшиеся для установки мадальности окна, были заменены на единственное перечисление, которое может быть использоваться для указания модального поведения виджетов верхнего уровня:
Тип в Qt 3 | Эквивалент в Qt 4 |
---|---|
Qt::WShowModal | Вместо этого используйте QWidget::setWindowModality(Qt::ApplicationModal). |
Qt::WGroupLeader | Используйте QWidget::setWindowModality(Qt::WindowModal) для каждого дочернего диалога лидера группы (group leader), но не изменяйте модальность самого лидера группы. |
Некоторые свойства были переименованы в Qt 4, чтобы сделать Qt API более последовательным и более интуитивным. Например, свойство QWidget'а - caption - было переименовано в windowTitle чтобы сделать понятным, что оно относится к заголовку показываемому в панели заголовка окна.
Кроме того, система свойств была расширена чтобы разрешить переопределение свойств в подклассах с помощью макроса Q_PROPERTY(), устраняя необходимость в макросе Q_OVERRIDE().
В таблице ниже перечислены свойства, которые были переименованы в Qt 4. Случаи их вхождения в UI файлах Qt Designer автоматически преобразуются uic'ом к новым именам.
Имя в Qt 3 | Имя в Qt 4 |
---|---|
QButton::accel | QButton::shortcut |
QButton::on | QButton::checked |
QButton::toggleButton | QAbstractButton::checkable |
QDial::lineStep | QDial::singleStep |
QDial::maxValue | QDial::maximum |
QDial::minValue | QDial::minimum |
QDialog::modal | QDialog::isModal |
QLineEdit::edited | QLineEdit::modified |
QLineEdit::hasMarkedText | QLineEdit::hasSelectedText |
QLineEdit::markedText | QLineEdit::selectedText |
QObject::name | QObject::objectName |
QProgressDialog::progress | QProgressDialog::value |
QProgressDialog::totalSteps | QProgressDialog::maximum |
QProgressDialog::wasCancelled | QProgressDialog::wasCanceled |
QPushButton::iconSet | QPushButton::icon |
QScrollBar::draggingSlider | QScrollBar::sliderDown |
QScrollBar::lineStep | QScrollBar::singleStep |
QScrollBar::maxValue | QScrollBar::maximum |
QScrollBar::minValue | QScrollBar::minimum |
QSlider::lineStep | QSlider::singleStep |
QSlider::maxValue | QSlider::maximum |
QSlider::minValue | QSlider::minimum |
QSpinBox::lineStep | QSpinBox::singleStep |
QSpinBox::maxValue | QSpinBox::maximum |
QSpinBox::minValue | QSpinBox::minimum |
QTabBar::currentTab | QTabBar::currentIndex |
QTabWidget::currentPage | QTabWidget::currentWidget |
QToolButton::iconSet | QToolButton::icon |
QToolButton::textLabel | QToolButton::text |
QWidget::caption | QWidget::windowTitle |
QWidget::icon | QWidget::windowIcon |
QWidget::iconText | QWidget::windowIconText |
Несколько свойств Qt 3 больше не являются свойствами в Qt 4, но функции доступа все еще существуют как часть Qt 4 API. Они не используются Qt Designer'ом; единственное обстоятельство когда вам нужно беспокоиться о них - в высоко динамичных приложениях, которые используют мета-объектную систему Qt для получения доступа к свойствам. Вот список этих свойств с функциями чтения и записи, которые вы можете использовать вместо них:
Свойство в Qt 3 | Функция чтения в Qt 4 | Функция записи в Qt 4 |
---|---|---|
QSqlDatabase::connectOptions | QSqlDatabase::connectOptions() | QSqlDatabase::setConnectOptions() |
QSqlDatabase::databaseName | QSqlDatabase::databaseName() | QSqlDatabase::setDatabaseName() |
QSqlDatabase::hostName | QSqlDatabase::hostName() | QSqlDatabase::setHostName() |
QSqlDatabase::password | QSqlDatabase::password() | QSqlDatabase::setPassword() |
QSqlDatabase::port | QSqlDatabase::port() | QSqlDatabase::setPort() |
QSqlDatabase::userName | QSqlDatabase::userName() | QSqlDatabase::setUserName() |
Некоторые свойства в 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 (QT3_SUPPORT) | Функция записи Qt 4 (QT3_SUPPORT) |
---|---|---|
QMenuBar::separator | QMenuBar::separator() | QMenuBar::setSeparator() |
QPushButton::menuButton | QPushButton::isMenuButton() | Нет данных |
QTabWidget::margin | QTabWidget::margin() | QTabWidget::setMargin() |
QTextEdit::textFormat | QTextEdit::textFormat() | QTextEdit::setTextFormat() |
QWidget::backgroundBrush | QWidget::backgroundBrush() | Нет данных |
QWidget::backgroundMode | QWidget::backgroundMode() | QWidget::setBackgroundMode() |
QWidget::backgroundOrigin | QWidget::backgroundOrigin() | QWidget::setBackgroundOrigin() |
QWidget::colorGroup | QWidget::colorGroup() | QWidget::setColorGroup() |
QWidget::customWhatsThis | QWidget::customWhatsThis() | QWidget::setCustomWhatsThis() |
QWidget::inputMethodEnabled | QWidget::inputMethodEnabled() | QWidget::setInputMethodEnabled() |
QWidget::ownCursor | QWidget::ownCursor() | Нет данных |
QWidget::ownFont | QWidget::ownFont() | Нет данных |
QWidget::ownPalette | QWidget::ownPalette() | Нет данных |
QWidget::paletteBackgroundColor | QWidget::paletteBackgroundColor() | QWidget::setPaletteBackgroundColor() |
QWidget::paletteBackgroundPixmap | QWidget::paletteBackgroundPixmap() | QWidget::setPaletteBackgroundPixmap() |
QWidget::paletteForegroundColor | QWidget::paletteForegroundColor() | QWidget::setPaletteForegroundColor() |
QWidget::underMouse | QWidget::underMouse() | Нет данных |
Следующие свойства Qt 3 и их функции доступа более недоступны в Qt 4. В большинстве случаев Qt 4 предоставляет аналогичную функциональность.
Свойство в Qt 3 | Эквивалент в Qt 4 |
---|---|
QButton::autoRepeat | Нет данных |
QButton::autoResize | Вызывайте QWidget:setFixedSize(QWidget::sizeHint()) всякий раз, когда изменяете содержимое. |
QButton::exclusiveToggle | Смотрите QAbstractButton::autoExclusive. |
QButton::pixmap | Вместо этого используйте QAbstractButton::icon. |
QButton::toggleState | Вместо этого используйте QCheckBox::setState() и QCheckBox::state(). |
QButton::toggleType | Вместо этого используйте QCheckBox::setTristate(). |
QComboBox::autoResize | Вызывайте QWidget:setFixedSize(QWidget::sizeHint()) всякий раз, когда изменяете содержимое. |
QFrame::contentsRect | Вместо этого используйте Q3Frame::contentsRect(). |
QFrame::margin | Вместо этого используйте QWidget::setContentsMargins(). |
QTabBar::keyboardFocusTab | Нет данных |
QToolButton::offIconSet | Вместо этого используйте off component для QAbstractButton::icon. |
QToolButton::onIconSet | Вместо этого используйте on component для QAbstractButton::icon. |
QWidget::microFocusHint | Нет данных |
QMimeSource::serialNumber () | Нет данных |
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 был переименован в Q3Accel и перемещен в модуль Qt3Support. В новых приложения у вас есть три варианта:
Класс Q3Accel также поддерживает многочисленные быстрые клавиши используя один и тот же объект, многократно вызывая Q3Accel::insertItem(). В Qt 4 решение заключается в создании нескольких объектов QShortcut.
Класс QAccessibleInterface подвергся в Qt 4 некоторым изменениям API для того, чтобы сделать его более согласованным с остальным Qt API.
Если у вас есть классы, которые унаследованы от QAccessibleInterface или одного из его подклассов (QAccessibleObject, QAccessibleWidget и т.д.), вы должны портировать их на новый API QAccessibleInterface.
Смотрите в Виртуальных функциях список виртуальных функций-членов QAccessibleInterface в Qt 3, которые больше не являются виртуальными в Qt 4.
QAccessibleTitleBar был переименован в Q3AccessibleTitleBar и перемещен в библиотеку Qt3Support.
Класс QAction был перепроектирован в Qt 4 чтобы лучше интегрироваться с другими системами меню. Он объединяет старые классы QMenuItem и QAction в один класс, избегая излишнего дублирования данных и необходимости изучать два разных API.
Старые классы QAction и QActionGroup были переименованы в Q3Action и Q3ActionGroup, соответственно, и перемещены в Qt3Support. Кроме того, новый класс QAction имеет функции совместимости для облегчения перехода на Qt 4. Обратите внимание на то, что при использовании Q3ToolBar и Q3PopupMenu их действия должны быть объектами Q3Action.
Смотрите в Виртуальных функциях список виртуальных функций-членов QAction в Qt 3, которые больше не являются виртуальными в Qt 4.
Класс QAction был полностью перепроектирован в Qt 4 чтобы лучше интегрироваться с другими системами меню. За подробностями обращайтесь к разделу в QAction.
Класс QApplication был разделен на два класса: QCoreApplication и QApplication. Новый класс QApplication унаследован от QCoreApplication и добавляет функциональность, связанную с ГПИ. Фактически, это не имеет последствий для имеющихся приложений Qt.
Кроме того, были сделаны следующие изменения API:
Кроме того, QWidgetList изменился с псевдонима типа (typedef) для QPtrList<QWidget> на псевдоним типа (typedef) для QList<QWidget *>. Подробности смотрите ниже в разделе в QWidgetList.
Например, если у вас есть код
QWidgetList *list = QApplication::topLevelWidgets(); QWidgetListIt it(*list); QWidget *widget; while ((widget = it.current())) { if (widget->inherits("MainWindow")) ((MainWindow *)widget)->updateRecentFileItems(); ++it; } delete list;
вы можете записать его в виде
QWidgetList list = QApplication::topLevelWidgets(); for (int i = 0; i < list.size(); ++i) { if (MainWindow *mainWin = qobject_cast<MainWindow *>(list.at(i))) mainWin->updateRecentFileItems(); }
Класс QAquaStyle впервые появился в Qt 3.0, когда впервые был выпущен порт Qt для Mac OS X. Он эмулировал тему "Aqua" от Apple. В Qt 3.1, QAquaStyle устарел с появлением QMacStyle, который использует Appearance Manager для выполнения своей отрисовки.
Класс QAquaStyle более не предоставляется в Qt 4. Используйте вместо него QMacStyle.
QAsciiCache<T> был переименован в Q3AsciiCache<T> и перемещен в библиотеку Qt3Support. Его заменил класс QCache<QByteArray, T>.
Подробности читайте в разделе в QCache<T>, заменяя в уме QByteArray на QString.
QAsciiDict<T> и QAsciiDictIterator<T> были переименованы в Q3AsciiDict<T> и Q3AsciiDictIterator<T>, соответственно, и перемещены в библиотеку Qt3Support. Их заменили более современные классы QHash<Key, T> и QMultiHash<Key, T>, соответственно, и их соответствующие классы-итераторы.
При портировании на Qt 4 старого кода, который использует Q3AsciiDict<T>, имеется четыре класса, которые вы можете использовать:
Подробности читайте в разделе в QDict<T>, заменяя в уме QByteArray на QString.
Класс QAsyncIO использовался для внутренних нужд в Qt 2.x в сочетании с QImageConsumer. Он устарел в Qt 3.0.
Если вы использовали этот механизм в своем приложении, пожалуйста, отправьте сообщение в Task Tracker на веб-сайте Qt и мы попытаемся найти удовлетворительную замену.
Недокументированный класс QBackInsertIterator был удален из библиотеки Qt. Если он необходим в вашем приложении, просто скопируйте исходный код из заголовочного файла <qtl.h> Qt 3.
В Qt 3 QBitArray унаследован от QByteArray. В Qt 4 QBitArray - полностью независимый класс. Это приводит к очень небольшим отличиям для пользователя, за исключением того, что новый класс QBitArray больше не предоставляет любых API QByteArray'а, основанных на байтах. Эти вызовы приведут к появлению ошибки времени компиляции, за исключением вызовов QBitArray::truncate(), чей параметр был количеством байт в Qt 3 и количеством бит в Qt 4.
В Qt 3 QBitArray был классом с явным разделением данных. Для получения дополнительной информации смотрите Явное разделение данных.
Класс QBitVal был переименован в QBitRef.
Класс 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); }
Функция Q3Button | Эквивалент QAbstractButton |
---|---|
Q3Button::autoResize() | Вызывайте QWidget:setFixedSize(QWidget::sizeHint()) всякий раз, когда изменяете содержимое. |
Q3Button::isExclusiveToggle() | Вместо этого используйте QAbstractButton::group() или QAbstractButton::autoExclusive(). |
Q3Button::pixmap() const | QAbstractButton::icon() |
Q3Button::setAutoResize() | Нет данных |
Q3Button::setPixmap(const QPixmap &) | QAbstractButton::setIcon(const QIcon &) |
Q3Button::setState(ToggleState) | Смотрите замечание ниже |
Q3Button::setToggleType(ToggleType) | Смотрите замечание ниже |
Q3Button::state() | Смотрите замечание ниже |
Q3Button::stateChanged(int) | Смотрите замечание ниже |
Q3Button::toggleType() | Смотрите замечание ниже |
Замечания:
Смотрите в Виртуальных функциях список виртуальных функций-членов QButton в Qt 3, которые не являются виртуальными в Qt 4.
Смотрите в Свойствах список свойств QButton в Qt 3, которые изменились в Qt 4.
Класс 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.
В Qt 3 QByteArray был просто псевдонимом (typedef) для QMemArray<char>. В Qt 4 QByteArray - отдельный класс с высокоуровневым API в стиле QString.
Вот основные известные проблемы при портировании на Qt 4:
Например, если у вас есть код
QByteArray ba(64);
вы можете записать его в виде
QByteArray ba(64, '\0');
ba.at(0) = 'X';
больше не компилируется. Вместо этого используйте QByteArray::operator[]:
ba[0] = 'X';
В Qt 3 QByteArray был классом с явным разделением данных. Для получения дополнительной информации смотрите Явное разделение данных.
QCache<T> переименован в Q3Cache<T> и перенесен в Qt3Support. Новый класс QCache имеет другой API и получает другой шаблон параметров: QCache<Key, T>.
При портировании на Qt 4, QCache<QString, T> является очевидной заменой для Q3Cache<T>. В следующей таблице приведены различия в API.
Функция Q3Cache<T> | Эквивалент QCache<QString, T> |
---|---|
Q3Cache::Q3Cache(int maxCost, int size, bool caseSensitive) | Смотрите замечание ниже |
Q3Cache::autoDelete() | Нет данных |
Q3Cache::count() | QCache::count() или QCache::size() (эквивалентны) |
Q3Cache::setAutoDelete() | Смотрите замечание ниже |
Q3Cache::size() | Нет данных |
Q3Cache::statistics() | Нет данных |
Q3Cache::operator=() | Смотрите замечание ниже |
Замечания:
if (!cache.insert(key, object)) delete object;
становится
cache.insert(key, object);
Q3Cache<QWidget> cache; cache.insert(widget->name(), widget); ... QWidget *foo = cache.take("foo"); if (foo) foo->show();
становится
typedef QWidget *QWidgetPtr; QCache<QString, QWidgetPtr> cache; cache.insert(widget->name(), new QWidgetPtr(widget)); ... QWidgetPtr *ptr = cache.take("foo"); if (ptr) { QWidget *foo = *ptr; delete ptr; foo->show(); }
Альтернативой является продолжение использования Q3Cache.
QCacheIterator<T> был переименован в Q3CacheIterator<T> и перемещен в библиотеку Qt3Support. Новый класс QCache не предлагает никаких типов итераторов.
Классы модуля canvas были переименованы и перемещены в библиотеку Qt3Support.
Имя класса в Qt 3 | Класс совместимости в Qt 4 |
---|---|
QCanvas | Q3Canvas |
QCanvasEllipse | Q3CanvasEllipse |
QCanvasItem | Q3CanvasItem |
QCanvasItemList | Q3CanvasItemList |
QCanvasLine | Q3CanvasLine |
QCanvasPixmap | Q3CanvasPixmap |
QCanvasPixmapArray | Q3CanvasPixmapArray |
QCanvasPolygon | Q3CanvasPolygon |
QCanvasPolygonalItem | Q3CanvasPolygonalItem |
QCanvasRectangle | Q3CanvasRectangle |
QCanvasSpline | Q3CanvasSpline |
QCanvasSprite | Q3CanvasSprite |
QCanvasText | Q3CanvasText |
QCanvasView | Q3CanvasView |
Каркас Графического представления заменил QCanvas. Подробности о портировании на Графическое представление смотрите в Переход на Графическое представление.
В 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);
В 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 был переименован в Q3ColorDrag и перемещен в библиотеку Qt3Support. В Qt 4 используйте взамен QMimeData и вызовите QMimeData::setColor() для установки цвета.
В Qt 3 список выбора использовался для вывода на экран содержимого виджета QComboBox, получить доступ к нему можно используя функцию listBox(). В Qt 4 стандартный список выбора предоставляется виджетом QListView, и можно получить доступ с помощью функции view().
Смотрите в Виртуальных функциях список виртуальных функций-членов QComboBox в Qt 3, которые больше не являются виртуальными в Qt 4.
В 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:
Функция Q3CString | Эквивалент в Qt 4 |
---|---|
Q3CString::Q3CString(const char *, uint) | Смотрите замечание ниже |
Q3CString::Q3CString(int) | QByteArray::QByteArray(int, char) |
Q3CString::leftJustify() | QString::leftJustified() |
Q3CString::length() | QByteArray::length() или QByteArray::size() (эквивалентны) |
Q3CString::lower() | QByteArray::toLower() |
Q3CString::rightJustify() | QString::rightJustified() |
Q3CString::setExpand() | Смотрите замечание ниже |
Q3CString::simplifyWhiteSpace() | QByteArray::simplified() |
Q3CString::sprintf() | QString::sprintf() |
Q3CString::stripWhiteSpace() | QByteArray::trimmed() |
Q3CString::toDouble() | QString::toDouble() |
Q3CString::toFloat() | QString::toFloat() |
Q3CString::toInt() | QString::toInt() |
Q3CString::toLong() | QString::toLong() |
Q3CString::toShort() | QString::toShort() |
Q3CString::toUInt() | QString::toUInt() |
Q3CString::toULong() | QString::toULong() |
Q3CString::toUShort() | QString::toUShort() |
Q3CString::upper() | QByteArray::toUpper() |
Замечания:
Например, если у вас есть код
QCString str1("Hello", 4); // "Hel" QCString str2("Hello world!", n);
вы можете записать его в виде
QByteArray str1("Hello", 3); QByteArray str2("Hello world!"); str2.truncate(n - 1);
Например, если у вас есть код
QCString str("Hello world"); str.setExpand(16, '\n'); // "Hello world \n"
вы можете записать его в виде
QByteArray str("Hello world"); while (str.size() < 16) str += ' '; str += '\n';
Так как старый класс QCString унаследован от QByteArray, все что сказано в разделе QByteArray также применимо и для QCString.
В Qt 3 разработчики могли создать пользовательское событие создавая новый QCustomEvent, и отправляя соответствующие данные другим компонентам в приложении передавая указатель void, либо на структуру, либо используя функцию setData(). Объекты могут получать пользовательские события, переопределив функцию customEvent() и получив доступ к сохраненным данным, используя функцию data() события.
В Qt 4 пользовательские события создаются созданием подклассов QEvent. Данные зависимые от событий могут быть сохранены способом, который подходит для вашего приложения. Пользовательские события по-прежнему доставляются каждой функции-обработчику customEvent() объекта, но как объекты QEvent лучше, чем как устаревшие объекты QCustomEvent.
Класс QDataBrowser был переименован в Q3DataBrowser и перемещен в библиотеку Qt3Support. В Qt 4.2 вы должны использовать класс QDataWidgetMapper для создания дата-ориентированных (data-aware) форм.
Обзор новых классов SQL смотрите в Модуле QtSql.
Класс QDataPump использовался для внутренних нужд в Qt 2.x в сочетании с QImageConsumer. Он устарел в Qt 3.0.
Если вы использовали этот механизм в своем приложении, пожалуйста, отправьте сообщение в Task Tracker на веб-сайте Qt и мы попытаемся найти удовлетворительную замену.
Класс QDataSink использовался для внутренних нужд в Qt 2.x в сочетании с QImageConsumer. Он устарел в Qt 3.0.
Если вы использовали этот механизм в своем приложении, пожалуйста, отправьте сообщение в Task Tracker на веб-сайте Qt и мы попытаемся найти удовлетворительную замену.
Класс QDataSource использовался для внутренних нужд в Qt 2.x в сочетании с QImageConsumer. Он устарел в Qt 3.0. Если вы использовали этот механизм в своем приложении, пожалуйста, отправьте сообщение в Task Tracker на веб-сайте Qt и мы попытаемся найти удовлетворительную замену.
Класс QDataTable был переименован в Q3DataTable и перемещен в библиотеку Qt3Support. В Qt 4.2 вы должны использовать класс QDataWidgetMapper для создания дата-ориентированных (data-aware) форм.
Обзор новых классов SQL смотрите в Модуле QtSql.
Класс QDataView был переименован в Q3DataView и перемещен в библиотеку Qt3Support. В Qt 4.2 вы должны использовать класс QDataWidgetMapper для создания дата-ориентированных (data-aware) форм.
Обзор новых классов SQL смотрите в Модуле QtSql.
В Qt 4 класс QDateEdit является вспомогательным классом, основанным на QDateTimeEdit. Старый класс был переименован в Q3DateEdit и перемещен в библиотеку Qt3Support.
Смотрите в Виртуальных функциях список виртуальных функций-членов QDateEdit в Qt 3, которые больше не являются виртуальными в Qt 4.
Класс QDateTimeEditBase был переименован в Q3DateTimeEditBase и перемещен в Qt3Support. Вместо этого используйте QDateTimeEdit или QAbstractSpinBox.
Старый класс QDateTimeEdit был переименован в Q3DateTimeEditBase и перемещен в Qt3Support. Новый класс QDateTimeEdit в Qt 4 был переписан с нуля для предоставления большей гибкого и мощного API.
Смотрите в Виртуальных функциях список виртуальных функций-членов QDateTimeEdit в Qt 3, которые больше не являются виртуальными в Qt 4.
Класс 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 в Qt 3, которые больше не являются виртуальными в Qt 4.
Смотрите в Свойствах список свойств QDial в Qt 3, которые изменились в Qt 4.
QDict<T> был переименован в Q3Dict<T> и перемещен в Qt3Support. Его заменили более современные классы QHash<Key, T> и QMultiHash<Key, T>.
При портировании на Qt 4 старого кода, использующего QDict<T> имеется четыре класса, которые вы можете использовать:
Класс в Qt 4 | Когда используется |
---|---|
QMultiHash<QString, T *> | Так как Q3Dict<T> основан на указателях и разрешает дублирование ключей, то обычно это более простое преобразование. |
QMultiHash<QString, T> | Если тип T является присваиваемым типом данных, вы можете использовать T, а не тип-значение T *. Это часто приводит к более элегантному коду. |
QHash<QString, T *> | Если вы не используете дублирующиеся ключи, вы можете использовать QHash вместо QMultiHash. QMultiHash унаследован от QHash. |
QHash<QString, T> |
API Q3Dict<T> и QMultiHash<QString, T *> очень похожи. Основной проблемой является то, что Q3Dict поддерживает автоудаление тогда как QMultiHash - нет.
В следующей таблице приведены различия в API между двумя классами:
Функция Q3Dict | Эквивалент QMultiHash |
---|---|
Q3Dict::Q3Dict(int size, bool caseSensitive) | Смотрите замечания ниже |
Q3Dict::autoDelete() | Нет данных |
Q3Dict::count() | QMultiHash::count() или QMultiHash::size() (эквивалентны) |
Q3Dict::find(const QString &) | QMultiHash::value(const QString &) |
Q3Dict::remove(const QString &) | QMultiHash::take(const QString &) |
Q3Dict::resize(uint) | QMultiHash::reserve(int) |
Q3Dict::setAutoDelete() | Смотрите замечание ниже |
Q3Dict::size() | QMultiHash::capacity() |
Q3Dict::statistics() | Нет данных |
Q3Dict::operator[](const QString &) | Смотрите замечание ниже |
Замечания:
Если вы используете возможность Q3Dict'а -автоудаление (вызывая Q3Dict::setAutoDelete(true)), вам нужно сделать немного больше работы. У вас есть два варианта: Вы либо сами вызываете delete всякий раз, когда удаляете элемент из контейнера, либо вы используете QMultiHash<QString, T> вместо QMultiHash<QString, T *> (т.е. сохраняете непосредственно значения вместо указателей на значения). Здесь мы увидим когда вызвать delete.
В следующей таблице приведены стили, которые вам нужно знать, если вы хотите сами вызывать delete.
Стиль Q3Dict | Стиль QMultiHash |
---|---|
dict.replace(key, value); | delete hash.take(key); hash.insert(key, value); |
dict.remove(key, value); | delete hash.take(key); |
dict.clear(); (also called from Q3Dict's destructor) | while (!hash.isEmpty()) { T *value = *hash.begin(); hash.erase(hash.begin()); delete value; } В 99% случаев следующий стиль также работает: qDeleteAll(hash); hash.clear(); Тем не менее, это может привести к аварийному отказу, если на hash ссылаются из деструктора типа-значения, потому что hash содержит висячие указатели до вызова clear(). |
Имейте в виду, что деструктор Q3Dict'а автоматически вызывает clear(). Если у вас в пользовательском классе имеется член данных Q3Dict и вы используете возможность автоудаления, то чтобы избежать утечки памяти вам будет нужно вызывать из деструктора вашего класса delete для всех элементов контейнера.
В заключение, QDictIterator<T> (переименованный Q3DictIterator<T>) должен также быть портирован. Имеется не менее четырех классов-итераторов, которые могут использоваться в качестве замены: QHash::const_iterator, QHash::iterator, QHashIterator и QMutableHashIterator. Проще всего использовать при портировании класс QHashIterator<QString, T *>. В следующей таблице приведены различия в API.
Функции Q3DictIterator | Эквивалент в Qt 4 |
---|---|
Q3DictIterator::count() | QHash::count() или QHash::size() |
Q3DictIterator::current() | QHashIterator::value() |
Q3DictIterator::currentKey() | QHashIterator::key() |
Q3DictIterator::isEmpty() | QHash::isEmpty() |
Q3DictIterator::toFirst() | QHashIterator::toFront() |
Q3DictIterator::operator()() | QHashIterator::value() |
Q3DictIterator::operator*() | QHashIterator::value() |
Q3DictIterator::operator++() | Смотрите замечание ниже |
Знайте, что 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.
Следующие используемые функции имеют булев параметр acceptAbsPath, который по умолчанию равен true:
В Qt 3, если acceptAbsPath равен true, имя файла начинающееся с '/' возвращалось без изменений; если acceptAbsPath равен false, в начало имени файла добавляется абсолютный путь. Например:
Текущий каталог | Имя файла | acceptAbsPath | Путь к файлу |
---|---|---|---|
/home/tsmith | index.html | true | /home/tsmith/index.html |
false | /home/tsmith/index.html | ||
/home/tsmith | /index.html | true | /index.html |
false | /home/tsmith/index.html |
В 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() и извлекайте путь отдельно.
Qt 3 использовал свою собственную реализацию протокола DNS и предоставлял низкоуровневый класс QDns. Вместо этого класс Qt 4 QHostInfo использует системную функцию gethostbyname() из потока.
Старый класс QDns был переименован в Q3Dns и перемещен в библиотеку Qt3Support. Новый класс QHostInfo имеет совершенно другой API: Он состоит главным образом из двух статических функций, одна из которых блокирующая (QHostInfo::fromName()), а другая неблокирующая (QHostInfo::lookupHost()). За подробностями обращайтесь к документации класса QHostInfo.
Класс QDockArea был переименован в Q3DockArea и перемещен в библиотеку Qt3Support. В Qt 4 QMainWindow самостоятельно обрабатывает области присоединения и панели инструментов. За подробностями обращайтесь к документации QMainWindow.
Старый класс QDockWindow был переименован в Q3DockWindow и перемещен в библиотеку Qt3Support. В Qt 4 имеется новый класс QDockWidget с отличающимся API. За подробностями обращайтесь к документации класса.
Смотрите в Виртуальных функциях список виртуальных функций-членов QDockWidget в Qt 3, которые больше не являются виртуальными в Qt 4.
Замечание: Свойство Q3DockWindow'а, horizontallyStretchable, может быть реализуется в QDockWidget с помощью политик размера.
Класс 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 был переименован в 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 был переименован в Q3EditorFactory и перемещен в библиотеку Qt3Support.
Обзор новых классов SQL смотрите в Модуле QtSql.
В Qt 3 QEventLoop сочетает цикл обработки событий Qt и диспетчеризацию событий. В Qt 4 эти задачи теперь разнесены по двум отдельным классам: QEventLoop и QAbstractEventDispatcher.
Если вы создали подкласс QEventLoop для интеграции с циклом обработки событий другой библиотеки, взамен вы должны создать подкласс QAbstractEventDispatcher. За подробностями обращайтесь к документации класса.
Разработчики, использовавшие QEventLoop::loopLevel() в Qt 3, должны использовать вместо нее QCoreApplication::loopLevel(). Обратите внимание на то, что эта функция помечена как устаревшая, но ожидается, что она будет доступна в течение времени жизни Qt 4.
Класс QFileDialog был полностью переписан в Qt 4. Он предоставляет большую часть функциональности старого класса QFileDialog, но с другим API. Добавление некоторой функциональности, например, возможности предварительного просмотра файлов, ожидается в следующих выпусках Qt 4.
Старые классы QFileDialog, QFileIconProvider и QFilePreview были переименованы в Q3FileDialog, Q3FileIconProvider и Q3FilePreview, соответственно, и перемещены в Qt3Support. Вы можете использовать их, если вам нужна некоторая функциональность, еще не предоставляемая новым классом QFileDialog.
В следующей таблице перечислены функции, которые были переименованы или удалены в Qt 4.
Старая функция | Эквивалент в Qt 4 |
---|---|
Q3FileDialog::addFilter(const QString &) | Смотрите замечание ниже |
Q3FileDialog::addLeftWidget(QWidget *) | Нет данных |
Q3FileDialog::addRightWidget(QWidget *) | Нет данных |
Q3FileDialog::addToolButton(QAbstractButton *, bool separator) | Нет данных |
Q3FileDialog::addWidgets(QLabel *, QWidget *, QPushButton *) | Нет данных |
Q3FileDialog::dir() | QFileDialog::directory() |
Q3FileDialog::dirPath() | QFileDialog::directory().path() |
Q3FileDialog::iconProvider() | Нет данных |
Q3FileDialog::isContentsPreviewEnabled() | Нет данных |
Q3FileDialog::isInfoPreviewEnabled() | Нет данных |
Q3FileDialog::previewMode() | Нет данных |
Q3FileDialog::rereadDir() | Нет данных |
Q3FileDialog::resortDir() | Нет данных |
Q3FileDialog::selectAll(bool) | Нет данных |
Q3FileDialog::setContentsPreview(QWidget *, Q3FilePreview *) | Нет данных |
Q3FileDialog::setContentsPreviewEnabled(bool) | Нет данных |
Q3FileDialog::setDir(const QString &) | QFileDialog::setDirectory(const QString &) |
Q3FileDialog::setFilters(const char **) | Q3FileDialog::setFilters(const QStringList &) |
Q3FileDialog::setIconProvider(Q3FileIconProvider *) | Нет данных |
Q3FileDialog::setInfoPreview(QWidget *, Q3FilePreview *) | Нет данных |
Q3FileDialog::setInfoPreviewEnabled(bool) | Нет данных |
Q3FileDialog::setPreviewMode(PreviewMode) | Нет данных |
Q3FileDialog::setSelectedFilter(const QString &) | QFileDialog::selectFilter(const QString &) |
Q3FileDialog::setSelectedFilter(int) | Смотрите замечание ниже |
Q3FileDialog::setSelection(const QString &) | QFileDialog::selectFile(const QString &) |
Q3FileDialog::setShowHiddenFiles(bool) | showHidden() |
Q3FileDialog::setUrl(const QUrlOperator &) | Нет данных |
Q3FileDialog::showHiddenFiles() | Нет данных |
Q3FileDialog::url() | QUrl::fromLocalFile(QFileDialog::directory()) |
Старые сигналы | Эквивалент в Qt 4 |
Q3FileDialog::fileHighlighted(const QString &) | Нет данных |
Q3FileDialog::fileSelected(const QString &) | QFileDialog::filesSelected(const QStringList &) |
Q3FileDialog::dirEntered(const QString &) | Нет данных |
Q3FileDialog::filterSelected(const QString &) | Нет данных |
Замечания:
Например, если у вас есть код
fileDialog->addFilter(tr("JPEG files (*.jpg *.jpeg)"));
вы можете записать его в виде
QStringList filters = fileDialog->filters(); filters << tr("JPEG files (*.jpg *.jpeg)"); fileDialog->setFilters(filters);
Например, если у вас есть код
fileDialog->setSelectedFilter(3);
вы можете записать его в виде
fileDialog->selectFilter(fileDialog->filters().at(3));
Не имеется эквивалентных виртуальных функций для двух виртуальных функций Q3FileDialog::setSelectedFilter() в API QFileDialog. Кроме того, эти функции переименованы или удалены, как описывалось выше.
Класс QFocusData не доступен в Qt 4. Некоторая его функциональность доступна через функции QWidget::nextInFocusChain() и QWidget::focusNextPrevChild().
Функции setReason() более нет в Qt 4. Необходимо определить причину при создании события фокуса.
QFont::Script была перемещена в QFontDatabase::WritingSystem.
Уменьшив в Qt 4 количество свойств и виртуальных функций класс QFrame был сделан более легким. Уменьшение количества виртуальных функций важно, поскольку QFrame является базовым классом многих классов Qt.
Вот обзор изменений:
Чтобы помочь с портированием библиотека Qt3Support содержит класс Q3Frame, который унаследован от QFrame и предоставляет API, аналогичный API старого класса QFrame. Если в вашем приложении вы наследовали от QFrame, вы можете захотеть использовать Q3Frame в качестве базового класса как первый этап процесса портирования, а позднее перейти на новый класс QFrame.
Смотрите в Виртуальных функциях список виртуальных функций-членов QFrame в Qt 3, которые больше не являются виртуальными в Qt 4.
QFtp больше не унаследован от QNetworkProtocol. За подробностями обращайтесь к разделу в QNetworkProtocol.
Старый класс QFtp был переименован в Q3Ftp и перемещен в библиотеку Qt3Support.
Класса QGLayoutIterator больше нет в Qt 4. Это приводит к отличиям только если вы реализовали пользовательские менеджеры компоновки (т.е., создали подклассы QLayout).
Новый подход значительно проще: Он состоит в переопределении QLayout::itemAt() и QLayout::takeAt(). Эти функции работают с индексами, устраняя необходимость в классе-итераторе компоновки.
Класс 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 в Qt 3, которые больше не являются виртуальными в Qt 4.
Класс QGridView был переименован в Q3GridView и перемещен в библиотеку Qt3Support. В Qt 4 мы рекомендуем использовать для представления табличных данных QTableView или QAbstractItemView.
Обзор новых классов представления элементов смотрите в Программирование модель/представление.
Класс QGroupBox был перепроектирован в Qt 4. Многие из функциональных возможностей старого класса QGroupBox можно получить использовав класс Q3GroupBox из библиотеки Qt3Support.
Новый QGroupBox более легкий. Он не пытается дублировать функциональность, уже предоставляемую QGridLayout, и он не унаследован от QFrame. В результате, следующие члены были удалены:
Естественно, свойства columns и orientation также удалены.
Если ваше приложение зависит от недостающей функциональности, в качестве помощи при портировании вы можете использовать Q3GroupBox вместо QGroupBox.
Смотрите в Виртуальных функциях список виртуальных функций-членов QGroupBox в Qt 3, которые больше не являются виртуальными в Qt 4.
Класс 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 был переименован в Q3Header и перемещен в библиотеку Qt3Support. В Qt 4 его заменил класс QHeaderView.
Обзор новых классов представления элементов смотрите в Программирование модель/представление.
Класс QHGroupBox был переименован в Q3HGroupBox и перемещен в библиотеку Qt3Support. Qt 4 не предоставляет конкретного класса замены для QHGroupBox поскольку QGroupBox спроектирован виджетом обобщенного контейнера. В результате, вам нужно обеспечить вашу собственную компоновку для любых дочерних виджетов.
Для получения дополнительной информации о портировании кода, который использует групповые рамки, смотрите #QGroupBox.
QHttp больше не унаследован от QNetworkProtocol. За подробностями обращайтесь к разделу в QNetworkProtocol.
Старые классы QHttp, QHttpHeader, QHttpRequestHeader и QHttpResponseHeader были переименованы в Q3Http, Q3HttpHeader, Q3HttpRequestHeader и Q3HttpResponseHeader, соответственно, и перенесены в библиотекуQt3Support.
Класс QIconFactory больше не является частью Qt. Его заменил класс QIconEngine.
Класс QIconSet больше не является частью Qt. Его заменил класс QIcon.
Классы QIconView, QIconViewItem, QIconDrag и QIconDragItem были переименованы в Q3IconView, Q3IconViewItem, Q3IconDrag и Q3IconDragItem, соответственно, и перемещены в библиотеку Qt3Support. Вместо этого в новых приложениях Qt должен использоваться QListWidget или его базовый класс QListView, и вызывать QListView::setViewMode(QListView::IconMode) для получения внешнего вида "в виде пиктограмм".
Обзор новых классов представления элементов смотрите в Программирование модель/представление.
Класс QImageDrag был переименован в Q3ImageDrag и перемещен в Qt3Support. В Qt 4 используйте взамен QMimeData и вызовите QMimeData::setImage() для установки изображения.
Смотрите Портирование на Qt 4 - Перетаскивание для сравнения API перетаскивания в Qt 3 и Qt 4.
Класс QImageIO был разделена на два класса: QImageReader и QImageWriter. В таблице ниже показано соответствие двух API:
Функция в Qt 3 | Эквиваленты в Qt 4 |
---|---|
QImageIO::description() | QImageWriter::text() |
QImageIO::fileName() | QImageReader::fileName() и QImageWriter::fileName() |
QImageIO::format() | QImageReader::format() и QImageWriter::format() |
QImageIO::gamma() | QImageWriter::gamma() |
QImageIO::image() | Возвращаемое значение функции QImageReader::read() |
QImageIO::inputFormats() | QImageReader::supportedImageFormats() |
QImageIO::ioDevice() | QImageReader::device() и QImageWriter::device() |
QImageIO::outputFormats() | QImageWriter::supportedImageFormats() |
QImageIO::parameters() | Нет данных |
QImageIO::quality() | QImageWriter::quality() |
QImageIO::read() | QImageReader::read() |
QImageIO::setDescription() | QImageWriter::setText() |
QImageIO::setFileName() | QImageReader::setFileName() и QImageWriter::setFileName() |
QImageIO::setFormat() | QImageReader::setFormat() и QImageWriter::setFormat() |
QImageIO::setGamma() | QImageWriter::setGamma() |
QImageIO::setIODevice() | QImageReader::setDevice() и QImageWriter::setDevice() |
QImageIO::setImage() | Аргумент для QImageWriter::write() |
QImageIO::setParameters() | Нет данных |
QImageIO::setQuality() | QImageWriter::setQuality() |
QImageIO::setStatus() | Нет данных |
QImageIO::status() | QImageReader::error() и QImageWriter::error() |
QImageIO::write() | QImageWriter::write() |
QIntCache<T> был перемещен в модуль Qt3Support. Он был заменен QCache<int, T>.
Подробности читайте в разделе в QCache<T>, заменяя в уме int на QString.
QIntDict<T> и QIntDictIterator<T> были перемещены в Qt3Support. Их заменили более современные классы QHash<Key, T> и QMultiHash<Key, T> и связанные с ними классы-итераторы.
При портировании на Qt 4 старого кода, который использует QIntDict<T>, имеется четыре класса, которые вы можете использовать:
Подробности читайте в разделе в QDict<T>, заменяя в уме int на QString.
API класса QIODevice был упрощен чтобы облегчить создание подклассов и чтобы сделать его работу более ровной с асинхронными устройствами, например, QTcpSocket и QProcess.
У следующих виртуальных функциях изменилось имя или сигнатура:
Функция в Qt 3 | Комментарий |
---|---|
QIODevice::at() const | Переименован в QIODevice::pos(). |
QIODevice::at(Offset) | Переименован в QIODevice::seek(). |
QIODevice::open(int) | Теперь параметр имеет тип QIODevice::OpenMode. |
QIODevice::readBlock(char *, Q_ULONG) | QIODevice::read(char *, qint64) |
QIODevice::writeBlock(const char *, Q_ULONG) | QIODevice::write(const char *, qint64) |
Замечание: QIODevice::open(QIODevice::OpenMode) больше не является чистой виртуальной.
Следующие функции больше не являются виртуальными или больше не существуют:
QIODevice::getch() | Переименовали QIODevice::getChar() и реализовали на основе QIODevice::readData(). |
QIODevice::putch(int) | Переименовали QIODevice::putChar() и реализовали на основе QIODevice::writeData(). |
QIODevice::readAll() | Реализована на основе QIODevice::readData(). |
QIODevice::readLine(char *, Q_ULONG) | Реализована на основе QIODevice::readData() |
QIODevice::ungetch(int) | Переименовали QIODevice::ungetChar() и искусственно используется внутренним буфером unget. |
Флаги IO_xxx были переработаны, а защищенная функция setFlags() удалена. Большинство флагов были ликвидированы, поскольку ошибки лучше обрабатываются реализацией конкретных функций в подклассах QIODevice нежели чем через базовые классы. Флаги доступа к файла, например, IO_ReadOnly и IO_WriteOnly, были перемещены в класс QIODevice чтобы избежать загрязнения глобального пространства имен. В таблице ниже показано соответствие между флагами IO_xxx в Qt 3 и Qt 4 API:
Константа в Qt 3 | Эквивалент в Qt 4 |
---|---|
IO_Direct | Вместо этого используйте !QIODevice::isSequential() (обращаем внимание на отрицание). |
IO_Sequential | Вместо этого используйте QIODevice::isSequential(). |
IO_Combined | Нет данных |
IO_TypeMask | Нет данных |
IO_Raw | QIODevice::Unbuffered |
IO_Async | Нет данных |
IO_ReadOnly | QIODevice::ReadOnly |
IO_WriteOnly | QIODevice::WriteOnly |
IO_ReadWrite | QIODevice::ReadWrite |
IO_Append | QIODevice::Append |
IO_Truncate | QIODevice::Truncate |
IO_Translate | QIODevice::Text |
IO_ModeMask | Нет данных |
IO_Open | Вместо этого используйте QIODevice::isOpen(). |
IO_StateMask | Нет данных |
IO_Ok | Нет данных |
IO_ReadError | Нет данных |
IO_WriteError | Нет данных |
IO_FatalError | Нет данных |
IO_ResourceError | Нет данных |
IO_OpenError | Нет данных |
IO_ConnectError | Нет данных |
IO_AbortError | Нет данных |
IO_TimeOutError | Нет данных |
IO_UnspecifiedError | Нет данных |
Класс QIODeviceSource использовался для внутренних нужд в Qt 2.x в сочетании с QImageConsumer. Он устарел в Qt 3.0. Если вы использовали этот механизм в своем приложении, пожалуйста, отправьте сообщение в Task Tracker на веб-сайте Qt и мы попытаемся найти удовлетворительную замену.
QLabel больше не разрешает автоматического выравнивания по словам при использовании форматированного текста. Вы можете разрешить это вызывая QLabel::setWordWrap() или установив свойство wordWrap. Причиной этого изменения является то, что старое поведение запутывало многих пользователей.
Также QLabel больше не предоставляет свойство autoResize. Взамен вы можете вызвать QWidget::setFixedSize() на метке, с QLabel::sizeHint() в качестве аргумента, всякий раз когда вы меняете содержимое QLabel.
Смотрите также в Виртуальных функциях список виртуальных функций-членов QLabel в Qt 3, которые больше не являются виртуальными в Qt 4.
В Qt 4 поля всегда обрабатываются компоновщиками; функции QLayout::setSupportsMargin() больше нет.
Функция deleteAllItems() теперь доступна только если определен QT3_SUPPORT. Если вы храните элементы компоновки в QList, вы можете использовать qDeleteAll() чтобы удалить все элементы сразу.
В Qt 3, для изменения поведения при изменении размеров компоновок в виджетах верхнего уровня можно было устанавливать свойство компоновки resizeMode. В Qt 4 это свойство заменено свойством QLayout::sizeConstraint, которое предоставляет больший контроль за поведением компоновки при изменении размеров.
Смотрите также раздел в QLayoutIterator и раздел в QGLayoutIterator.
Класс 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 в Qt 3, которые изменились в Qt 4.
Значение по умолчанию свойства QLineEdit'а - dragEnabled - в Qt 3 было true. В Qt 4 значение по умолчанию равно false.
Обратите внимание на то, что QLineEdit в Qt 4 более не является подклассом QFrame. Если вам нужно визуально применить стиль к однострочному редактору с рамкой, мы рекомендуем либо использовать QFrame в качестве контейнера для QLineEdit, либо настроить однострочный редактор с помощью таблиц стилей.
Классы QListBox, QListBoxItem, QListBoxText и QListBoxPixmap были переименованы в Q3ListBox, Q3ListBoxItem, Q3ListBoxText и Q3ListBoxPixmap, соответственно, и перемещены в библиотеку Qt3Support. В новых приложениях Qt вы должны использовать вместо них QListWidget или его базовый класс QListView.
Обзор новых классов представления элементов смотрите в Программирование модель/представление.
Классы QListView, QListViewItem, QCheckListItem и QListViewItemIterator были переименованы в Q3ListView, Q3ListViewItem, Q3CheckListItem и Q3ListViewItemIterator, соответственно, и перемещены в библиотеку Qt3Support. Новые приложения Qt должны использовать взамен один из четырех класса: QTreeView или QTreeWidget - для древовидных структур; QListWidget или новый класс QListView - для линейных списков.
Обзор новых классов представления элементов смотрите в Программирование модель/представление.
Класс QLocalFs больше не является частью открытого Qt API. Он был переименован в Q3LocalFs и перемещен в Qt3Support. Вместо этого используйте QDir, QFileInfo или QFile.
Класс QMainWindow был перепроектирован в Qt 4 чтобы предоставить более современный внешний вид и поведение, а также большую гибкость. Для отражения этого был изменен API. Старый класс QMainWindow был переименован в Q3MainWindow и перемещен в Qt3Support. За подробностями обращайтесь к документации класса QMainWindow.
QMemArray<T> был перемещен в Qt3Support. Он был заменен классом QVector<T>.
В следующей таблице приведены различия в API между двумя классами.
QMemArray::assign(const QMemArray<T> &) | QVector::operator=() |
QMemArray::assign(const T *, uint) | Смотрите замечание ниже |
QMemArray::duplicate(const QMemArray &) | QVector::operator=() |
QMemArray::duplicate(const T *, uint) | Смотрите замечание ниже |
QMemArray::setRawData(const T *, uint) | Нет данных |
QMemArray::resetRawData(const T *, uint) | Нет данных |
QMemArray::find(const T &, uint) | QVector::indexOf(const T &, int) |
QMemArray::contains(const T &) | QVector::count(const T &) |
QMemArray::sort() | qSort() |
QMemArray::bsearch(const T &d) | qBinaryFind() |
QMemArray::at(uint) | QVector::operator[]() |
QMemArray::operator const T *() | QVector::constData() |
Замечания:
Например, если у вас есть код
QMemArray<QSize> array; ... array.assign(data, size);
вы можете записать его в виде
QVector<QSize> vector; ... vector.resize(size); qCopy(data, data + size, vector.begin());
В Qt 3 QMenuBar наследовался от QFrame и QMenuData; в Qt 4 он является прямым подклассом QWidget. Приложения, которые предоставляют настраиваемые панели меню, могут получить преимущества возможностей применения стилей, описанные в документе Таблицы стилей Qt.
В Qt 4 невозможно добавить виджеты в панель меню.
В Qt 4 класс QMenu предоставляет виджет меню, который можно использовать во всех местах, где в приложении используются меню. В отличие от QMenuData, QMenu спроектирован вокруг концепции действий, предоставляемых классом QAction, взамен используемых в Qt 3 идентификаторов.
В Qt 3 можно было вставлять виджеты в меню используя специальную перегрузку QMenuData::insertItem(). В Qt 4.2 и старше, класс QWidgetAction может быть использован для обёртывания виджетов для использования в основанных на действиях API Qt 4.
Функция QMessageBox::iconPixmap() использовалась для возвращения "const QPixmap *". В Qt 4 она возвращает QPixmap.
QMimeSourceFactory был переименован в Q3MimeSourceFactory и перемещен в библиотеку Qt3Support. Новые приложения Qt должны взамен использовать Систему ресурсов Qt 4.
QMovie API был пересмотрен в Qt 4 чтобы сделать его более совместимым с остальными классами Qt (особенно QImageReader). В таблице ниже приведены изменения.
Функция в Qt 3 | Эквивалент в Qt 4 |
---|---|
QMovie::connectResize() | Соединяет с QMovie::resized() |
QMovie::connectStatus() | Соединяет с QMovie::stateChanged() |
QMovie::connectUpdate() | Соединяет с QMovie::updated() |
QMovie::disconnectResize() | Отсоединяет от QMovie::resized() |
QMovie::disconnectStatus() | Отсоединяет от QMovie::stateChanged() |
QMovie::disconnectUpdate() | Отсоединяет от QMovie::updated() |
QMovie::finished() | Вместо этого используйте QMovie::state() |
QMovie::frameImage() | Вместо этого используйте QMovie::currentImage() |
QMovie::frameNumber() | Вместо этого используйте QMovie::currentFrameNumber() |
QMovie::framePixmap() | Вместо этого используйте QMovie::currentPixmap() |
QMovie::getValidRect() | Вместо этого используйте frameRect() |
QMovie::isNull() | Вместо этого используйте QMovie::isValid() |
QMovie::pause() | Вместо этого используйте QMovie::setPaused(true) |
QMovie::paused() | Вместо этого используйте QMovie::state() |
QMovie::pushData() | Нет данных |
QMovie::pushSpace() | Нет данных |
QMovie::restart() | Вместо этого используйте QMovie::jumpToFrame(0) |
QMovie::running() | Вместо этого используйте QMovie::state() |
QMovie::step() | Вместо этого используйте QMovie::jumpToFrame() и QMovie::setPaused() |
QMovie::step() | Вместо этого используйте QMovie::jumpToNextFrame() |
QMovie::steps() | Вместо этого используйте QMovie::currentFrameNumber() и QMovie::frameCount() |
QMovie::unpause() | Вместо этого используйте QMovie::setPaused(false) |
Класс QMultiLineEdit в Qt 3 был вспомогательным подклассом QTextEdit, который предоставлял интерфейс, совместимый с классом Qt 2 QMultiLineEdit. В Qt 4 он называется Q3MultiLineEdit, унаследован от Q3TextEdit, и является частью Qt3Support. Используйте QTextEdit в новом коде.
Классы QNetworkProtocol, QNetworkProtocolFactoryBase, QNetworkProtocolFactory<T> и QNetworkOperation больше не являются частью открытого Qt API. Они были переименованы в Q3NetworkProtocol, Q3NetworkProtocolFactoryBase, Q3NetworkProtocolFactory<T> и Q3NetworkOperation, соответственно, и перемещены в библиотеку Qt3Support.
В приложениях Qt 4 вы можете использовать классы подобно QFtp и QNetworkAccessManager прямо для выполнения действий связанных с файлами на удаленном узле.
QObject::children() теперь возвращает QObjectList взамен указателя на QObjectList. Смотрите также примечания к QObjectList ниже.
Используйте QObject::findChildren() (или qFindChildren() если вам нужна совместимость с MSVC 6) взамен QObject::queryList(). Например:
QList<QWidget *> myWidgets = qFindChildren<QWidget *>(myParent);
QObject::killTimers() была удалена, поскольку была небезопасна для использования в подклассе. (Обычно подкласс не знает использует ли базовый класс таймеры или нет.)
Свойство QObject::name было переименовано в QObject::objectName.
QObject::objectTrees() была удалена. Если вы в основном заинтересованы в виджетах, используйте QApplication::allWidgets() или QApplication::topLevelWidgets().
Класс QObjectDictionary является синонимом для QAsciiDict<QMetaObject>. Смотрите раздел в QAsciiDict<T>.
В Qt 3 класс QObjectList был псевдонимом (typedef) для QPtrList<QObject>. В Qt 4 он является псевдонимом (typedef) для QList<QObject *>. Смотрите раздел в QPtrList<T>.
Для переопределения бэкендов рисовальщика предварительно необходимо переопределить виртуальную функцию QPaintDevice::cmd(). Эта функция удалена и должна быть заменена функцией QPaintDevice::paintEngine() и абстрактным классом QPaintEngine. QPaintEngine предоставляет виртуальные функции для всех операций рисования, которые могут выполняться в бэкенде рисовальщика.
bitBlt() и copyBlt() теперь являются только функциями совместимости. Вместо этого используйте QPainter::drawPixmap().
Все использовавшиеся функции, представляемые классом QPaintDeviceMetrics, теперь перемещены в QPaintDevice.
Например, если у вас есть код
QPaintDeviceMetrics metrics(widget); int deviceDepth = metrics.depth();
вы можете записать его в виде
int deviceDepth = widget->depth();
Для совместимости старый класс QPaintDeviceMetrics был переименован в Q3PaintDeviceMetrics и перемещен в Qt3Support.
Класс QPainter подвергся в Qt 4 некоторым изменениям, поскольку изменился способ отрисовки прямоугольников. В Qt 4 результат отрисовки QRect с пером толщиной в 1 пиксел на 1 пиксел шире и на 1 пиксел выше, чем в Qt 3.
Для совместимости мы предоставляем класс Q3Painter в Qt3Support, который обеспечивает старую семантику. За подробностями и причинами сделанных изменений обращайтесь к документации Q3Painter.
Перечисление QPainter::CoordinateMode было удалено в Qt 4. Все операции отсечения теперь описываются, используя логические координаты и являются предметом операций преобразования.
Перечисление QPainter::RasterOP было заменено на QPainter::CompositionMode.
В Qt 3 QPicture можно было сохранить в формат файла SVG. В Qt 4, поддержка SVG предоставляется модулем QtSvg, который включает в себя классы для вывода на экран содержимого файлов SVG.
Если вы хотите сгенерировать файлы SVG, вы можете использовать класс совместимости Q3Picture или введенный в Qt 4.3 класс QSvgGenerator.
Функция mask() была изменена так, чтобы возвращать ссылку на QBitmap, а не указатель. В результате, больше нет возможности просто проверить на нулевой указатель при определении имеет ли растровое изображение маску. Взамен, вам нужно явно проверить равна ли битовая маска нулю или нет.
Например, если у вас есть код
if (pixmap.mask()) widget->setMask(*pixmap.mask());
вы можете записать его в виде
if (!pixmap.mask().isNull()) widget->setMask(pixmap.mask());
Механизмы QPixmap::setOptimization() и QPixmap::setDefaultOptimization() более недоступны в Qt 4.
Класс 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 заменен на QMenu в Qt 4. Для совместимости со старыми приложениями, Q3PopupMenu предоставляет старый API и возможности, которые специфичны для всплывающих меню. Обратите внимание на то, что при использовании Q3PopupMenu действия меню должны быть объектами Q3Action.
В Qt 3 было общей практикой добавлять пункты во всплывающие меню, используя функцию insertItem(), сохраняющую идентификаторы для последующего использования; например, для динамического изменения элементов меню. В Qt 4 пункты меню полностью представляются действиями для согласованности с другими компонентами пользовательского интерфейса, например, кнопок панели инструментов. Создавайте новые меню с помощью класса QMenu, а для вставки новых пунктов используйте перегруженные функции QMenu::addAction(). Если вам нужно управлять набором действий, созданных для конкретного меню, мы советуем вам создать QActionGroup и добавить их в него.
Предоставленные Примеры главного окна показывают, как использовать систему действий Qt для создания меню, панелей инструментов и других общих распространенных элементов пользовательского интерфейса.
Класс QPrinter теперь ожидает настройку печати из QPrintDialog.
Класс QProcess подвергся значительному улучшению в Qt 4. Теперь наследуется от QIODevice, что делает возможным сочетание QProcess с QTextStream или QDataStream.
Старый класс QProcess был переименован в Q3Process и перемещен в библиотеку Qt3Support.
API класса QProgressBar было существенно улучшено в Qt 4. Старый API QProgressBar доступен как Q3ProgressBar в библиотеке Qt3Support.
API класса QProgressDialog был существенно улучшено в Qt 4. Старый API QProgressDialog доступен как Q3ProgressDialog в библиотеке Qt3Support.
Смотрите в Свойствах список свойств QProgressDialog в Qt 3, которые изменились в Qt 4.
Абстрактный базовый класс QPtrCollection<T> был переименован в Q3PtrCollection<T> и перемещен в библиотеку Qt3Support. В Qt 4 прямого эквивалента нет.
Список контейнеров Qt 4 смотрите в Базовых контейнерах.
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>, 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 | Эквивалент QList |
---|---|
QPtrList::contains(const T *) | QList::count(T *) |
QPtrList::containsRef(const T *) | QList::count(T *) |
QPtrList::find(const T *) | Смотрите замечание ниже |
QPtrList::findRef(const T *) | Смотрите замечание ниже |
QPtrList::getFirst() | QList::first() |
QPtrList::getLast() | QList::last() |
QPtrList::inSort(const T *) | Нет данных |
QPtrList::remove(const T *) | QList::removeAll(T *) |
QPtrList::remove(uint) | QList::removeAt(int) |
QPtrList::removeNode(QLNode *) | Нет данных |
QPtrList::removeRef(const T *) | QList::removeAll(T *) |
QPtrList::sort() | Смотрите замечание ниже |
QPtrList::takeNode(QLNode *) | Нет данных |
QPtrList::toVector(QGVector *) | Смотрите замечание ниже |
Замечания:
Например, если у вас есть код
QPtrList<QWidget> list; ... QPtrVector<QWidget> vector; list.toVector(&vector);
вы можете записать его в виде
QList<QWidget *> list; ... QVector<QWidget *> vector; vector.resize(list.size()); qCopy(list.begin(), list.end(), vector.begin());
Если вы используете возможность QPtrList'а - автоудаление (вызывая QPtrList::setAutoDelete(true)), вам нужно сделать немного больше работы. У вас есть два варианта: Вы либо сами вызываете delete всякий раз, когда удаляете элемент из контейнера, либо вы используете QList<T> вместо QList<T *> (т.е. сохраняете значения непосредственно взамен указателей на значения). Здесь мы увидим когда вызвать delete.
В следующей таблице приведены стили, которые вам нужно знать, если вы хотите сами вызывать delete.
Стиль QPtrList | Стиль QList |
---|---|
list.replace(index, value); | delete list[index]; list[index] = value; |
list.removeFirst(); | delete list.takeFirst(); |
list.removeLast(); | delete list.takeLast(); |
list.remove(index); | delete list.takeAt(index); |
list.remove(value); | int i = list.indexOf(value); if (i != -1) delete list.takeAt(i); |
list.remove(); (удаляет текущий элемент) | QMutableListIterator<T *> i; ... delete i.value(); i.remove(); |
list.clear(); (также вызывается деструктором QPtrList'а) | while (!list.isEmpty()) delete list.takeFirst(); В 99% случаев следующий стиль также работает: qDeleteAll(list); list.clear(); Тем не менее, это можно привести к аварийному отказу, если на list ссылаются из деструктора типа-значения, потому что list содержит висячие указатели до вызова clear(). |
Имейте в виду, что деструктор QPtrList'а автоматически вызывает clear(). Если у вас в пользовательском классе имеется член данных QPtrList и вы используете возможность автоудаления, то чтобы избежать утечки памяти вам будет нужно вызывать из деструктора вашего класса delete для всех элементов контейнера.
QPtrList имеет концепцию "текущего элемента", которая может быть использована для обхода списка без использования итератора. При портировании на Qt 4 вы можете использовать взамен класс в стиле Java QListIterator<T *> (или QMutableListIterator<T *>). В следующей таблице приведены различия в API.
Функция QPtrList | Эквивалент QListIterator |
---|---|
QPtrList::at() | Нет данных |
QPtrList::current() | QMutableListIterator::value() |
QPtrList::currentNode() | Нет данных |
QPtrList::findNext(const T *) | QListIterator::findNext(const T *) |
QPtrList::findNextRef(const T *) | QListIterator::findNext(const T *) |
QPtrList::first() | QPtrList::toFront() |
QPtrList::last() | QPtrList::toBack() |
QPtrList::next() | QPtrList::next() |
QPtrList::prev() | QPtrList::previous() |
QPtrList::remove() | QMutableListIterator::remove() |
QPtrList::take() | QMutableListIterator::remove() |
Имейте в виду, что 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.
Функция QPtrListIterator | Эквивалент в Qt 4 |
---|---|
QPtrListIterator::atFirst() | !QListIterator::hasPrevious() (обратите внимание на !) |
QPtrListIterator::atLast() | !QListIterator::hasNext() (обратите внимание на !) |
QPtrListIterator::count() | QList::count() или QList::size() |
QPtrListIterator::current() | QMutableListIterator::value() |
QPtrListIterator::isEmpty() | QList::isEmpty() |
QPtrListIterator::toFirst() | QListIterator::toFront() |
QPtrListIterator::toLast() | QListIterator::toBack() |
QPtrListIterator::operator() | QMutableListIterator::value() |
QPtrListIterator::operator*() | QMutableListIterator::value() |
Вновь, имейте ввиду, что 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 был перенесен в библиотеку Qt3Support. Его заменил более современный класс QQueue.
В следующей таблице приведены различия между QPtrQueue<T> и QQueue<T *>:
Функция QPtrQueue | Эквивалент QQueue |
---|---|
QPtrQueue::autoDelete() | Смотрите замечание ниже |
QPtrQueue::count() | QQueue::count() или QQueue::size() (эквивалентны) |
QPtrQueue::current() | QQueue::head() |
QPtrQueue::remove() | QQueue::dequeue() |
QPtrQueue::setAutoDelete() | Смотрите замечание ниже |
Если вы используете возможность QPtrQueue'а автоудаления (вызывая QPtrQueue::setAutoDelete(true)), вам нужно сделать немного больше работы. У вас есть два варианта: Вы либо сами вызываете delete всякий раз, когда удаляете элемент из контейнера, либо вы используете QQueue<T> вместо QQueue<T *> (т.е. сохраняете значения непосредственно взамен указателей на значения). Здесь мы увидим когда вызвать delete.
Стиль QPtrQueue | Стиль QQueue |
---|---|
queue.dequeue(); | delete queue.dequeue(); |
queue.remove(); | delete queue.dequeue(); |
queue.clear(); (также вызывается деструктором QPtrQueue'а) | while (!queue.isEmpty()) delete queue.dequeue(); В 99% случаев следующий стиль также работает: qDeleteAll(queue); queue.clear(); Тем не менее, это можно привести к аварийному отказу, если на queue ссылаются из деструктора типа-значения, потому что queue содержит висячие указатели до вызова clear(). |
QPtrStack был перемещен в библиотеку Qt3Support. Его заменил более современный класс QStack.
В следующей таблице приведены различия между QPtrStack<T> и QStack<T *>:
Функция QPtrStack | Эквивалент QStack |
---|---|
QPtrStack::autoDelete() | Смотрите замечание ниже |
QPtrStack::count() | QStack::count() или QStack::size() (эквивалентны) |
QPtrStack::current() | QStack::top() |
QPtrStack::remove() | QStack::pop() |
QPtrStack::setAutoDelete() | Смотрите замечание ниже |
Если вы используете возможность QPtrStack'а - автоудаление (вызывая QPtrStack::setAutoDelete(true)), вам нужно сделать немного больше работы. У вас есть два варианта: Вы либо сами вызываете delete всякий раз, когда удаляете элемент из контейнера, либо вы используете QStack<T> вместо QStack<T *> (т.е. сохраняете значения непосредственно взамен указателей на значения). Здесь мы увидим когда вызвать delete.
Стиль QPtrStack | Стиль QStack |
---|---|
stack.pop(); | delete stack.pop(); |
stack.remove(); | delete stack.pop(); |
stack.clear(); (также вызывается деструктором QPtrStack'а) | while (!stack.isEmpty()) delete stack.pop(); В 99% случаев следующий стиль также работает: qDeleteAll(stack); stack.clear(); Тем не менее, это можно привести к аварийному отказу, если на stack ссылаются из деструктора типа-значения, потому что stack содержит висячие указатели до вызова clear(). |
QPtrVector<T> был перемещен в Qt3Support. Его заменил более современный класс QVector.
При портировании на Qt 4 вы можете использовать QVector<T *> в качестве альтернативы для QPtrVector<T>. API QPtrVector<T> и QVector<T *> весьма похожи. Основной проблемой является то, что QPtrVector поддерживает автоудаление, тогда как QVector - нет.
В следующей таблице приведены различия в API между двумя классами:
Функция QPtrVector | Эквивалент QVector |
---|---|
QPtrVector::autoDelete() | Смотрите замечание ниже |
QPtrVector::bsearch(const T *) | qBinaryFind() |
QPtrVector::contains(const T *) | QVector::count(T *) |
QPtrVector::containsRef(const T *) | QVector::count(T *) |
QPtrVector::count() | Смотрите замечание ниже |
QPtrVector::insert(uint, T *) | Смотрите замечание ниже |
QPtrVector::isNull() | Нет данных |
QPtrVector::remove(uint) | Смотрите замечание ниже |
QPtrVector::setAutoDelete() | Смотрите замечание ниже |
QPtrVector::sort() | qSort() |
QPtrVector::take(uint) | Смотрите замечание ниже |
QPtrVector::toList(QGList *) | QList::QList(const QVector &) |
Замечания:
Например, если у вас есть код
int numValidItems = vect.count();
вы можете записать его в виде
int numValidItems = vect.size() - vect.count(0);
Если вы используете возможность QVector'а - автоудаление (вызывая QVector::setAutoDelete(true)), вам нужно сделать немного больше работы. У вас есть два варианта: Вы либо сами вызываете delete всякий раз, когда удаляете элемент из контейнера, либо вы используете QVector<T> вместо QVector<T *> (т.е. сохраняете значения непосредственно взамен указателей на значения). Здесь мы увидим когда вызвать delete.
В следующей таблице приведены стили, которые вам нужно знать, если вы хотите сами вызывать delete.
Стиль QPtrVector | Стиль QVector |
---|---|
vect.insert(i, ptr); | delete vect[i]; vect[i] = ptr; |
vect.remove(i); | delete vect[i]; vect[i] = 0; |
T *ptr = vect.take(i); | T *ptr = vect[i]; vect[i] = 0; |
vect.resize(n) | while (n > vect.size()) vect.append(0); while (n < vect.size() { T *ptr = vect.last(); vect.remove(vect.size() - 1); delete ptr; } |
vect.clear(); (также вызывается деструктором QPtrVector'а) | for (int i = 0; i < vect.size(); ++i) T *ptr = vect[i]; vect[i] = 0; delete ptr; } В 99% случаев следующий стиль также работает: qDeleteAll(vect); vect.clear(); Тем не менее, это можно привести к аварийному отказу, если на vect ссылаются из деструктора типа-значения, потому что vect содержит висячие указатели до вызова clear(). |
Имейте в виду, что деструктор QPtrVector'а автоматически вызывает clear(). Если у вас в пользовательском классе имеется член данных QPtrVector и вы используете возможность автоудаления, то чтобы избежать утечки памяти вам будет нужно вызывать из деструктора вашего класса delete для всех элементов контейнера.
Смотрите в Свойствах список свойств QPushButton в Qt 3, которые изменились в Qt 4.
В 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()); } };
Функции search() и searchRev() были переименованы в indexIn() и lastIndexIn(), соответственно.
В Qt 4 был сделаны следующие изменения в QRegion:
Смотрите в Свойствах список свойств QScrollBar в Qt 3, которые изменились в Qt 4.
Класс QScrollView был переименован в Q3ScrollView и перемещен в библиотеку Qt3Support. Его заменили классы QAbstractScrollArea и QScrollArea.
Обратите внимание на то, что Qt 4 использует в основном функцию QScrollArea::widget() там, где Qt 3 использовала QScrollView::viewport(). Основной причиной этого является то, что больше невозможно рисовать непосредственно на прокручиваемой области. Функция QScrollArea::widget() возвращает виджет, установленный на прокручиваемую область.
QScrollView был спроектирован для обхода 16-разрядного ограничения на координаты виджета, встречаемого в большинстве оконных систем. В Qt 4 это делается прозрачно для всех виджетов, поэтому больше нет необходимости в подобной функциональности в QScrollView. По этой причине новые классы QAbstractScrollArea и QScrollArea более легкие и сосредоточены на обработке полос прокрутки.
Класс QServerSocket был переименован в Q3ServerSocket и перемещен в библиотеку Qt3Support. В Qt 4 его заменил класс QTcpServer.
С помощью Q3ServerSocket, соединения принимаются переопределенной виртуальной функцией (Q3ServerSocket::newConnection()). С помощью QTcpServer, с другой стороны, вам не нужно создавать подклассы. Взамен просто присоедините к сигналу QTcpServer::newConnection().
Класс QSettings был переписан чтобы сделать его более устойчивым к ошибкам и соблюдающим существующие стандарты (например, формат файла INI). API также был сильно переработан. Старый API по-прежнему предоставляется при включенной поддержке Qt 3.
Поскольку между Qt 3 и Qt 4 форма и расположение настроек изменились, версия Qt 4 вашего приложения не распознает настройки, записанные с использованием Qt 3.
Класс 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 был переименован в Q3Signal и перемещен в библиотеку Qt3Support. Предпочтительный подход заключается в создании вашего собственного подкласса QObject с сигналом, который имеет желаемую сигнатуру. В качестве альтернативы вы можете вызвать QMetaObject::invokeMethod(), если вы хотите вызвать слот.
QSimpleRichText устарел с появлением 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::sliderStart() и QSlider::sliderRect() были удалены.
Прямоугольник ползунка можно теперь получить используя нижеприведенный фрагмент кода:
QSlider *slider; slider->style()->subControlRect(CC_Slider, sliderOption, SC_SliderHandle, slider);
В дополнение, направление вертикального QSlider'а изменилось, т.е. минимум теперь внизу, а максимум - вверху. Вы можете использовать свойство QAbstractSlider::invertedAppearance для управления этим поведением.
Смотрите в Свойствах список свойств QSlider в Qt 3, которые изменились в Qt 4.
Класс QSocket был переименован в Q3Socket и перемещен в библиотеку Qt3Support. В Qt 4 он был заменен классом QTcpSocket, который унаследовал от QAbstractSocket большую часть его функциональности.
Класс QSocketDevice был переименован в Q3SocketDevice и перемещен в библиотеку Qt3Support. В Qt 4 для Q3SocketDevice прямого эквивалента нет:
Класс QSortedList<T> устарел с Qt 3.0. В Qt 4 он был перемещен в библиотеку Qt3Support.
В новом коде мы рекомендуем вам использовать взамен QList<T> и использовать qSort() для сортировки элементов.
Функция setResizeMode() была перенесена в Qt3Support. Установите коэффициент растяжения в политике размеров виджета чтобы получить эквивалентную функциональность.
Устаревшая функция drawSplitter() была удалена. Используйте QStyle::drawPrimitive() чтобы получить аналогичную функциональность.
Смотрите в Свойствах список свойств QSpinBox в Qt 3, которые изменились в Qt 4.
Класс QSqlCursor был переименован в Q3SqlCursor и перемещен в библиотеку Qt3Support. В Qt 4 вы можете использовать QSqlQuery, QSqlQueryModel или QSqlTableModel, в зависимости от того нужен ли вам низкоуровневый или высокоуровневый интерфейс для доступа к базам данных.
Обзор новых классов SQL смотрите в Модуле QtSql.
QSqlDatabase - теперь интеллектуальный (smart) указатель, который передавался по значению. Просто замените все указатели QSqlDatabase на объекты QSqlDatabase.
Класс QSqlEditorFactory был переименован в Q3SqlEditorFactory и перемещен в Qt3Support.
Обзор новых классов SQL смотрите в Модуле QtSql.
Перечисление Type было переименовано в ErrorType, Значения были также переименованы:
Класс QSqlFieldInfo был перемещен в Qt3Support. Его функциональность теперь предоставляется классом QSqlField.
Обзор новых классов SQL смотрите в Модуле QtSql.
Класс QSqlForm был переименован в Q3SqlForm и перемещен в библиотеку Qt3Support.
Обзор новых классов SQL смотрите в Модуле QtSql.
Класс QSqlPropertyMap был переименован в Q3SqlPropertyMap и перемещен в библиотеку Qt3Support.
Обзор новых классов SQL смотрите в Модуле QtSql.
QSqlQuery::prev() была переименована в QSqlQuery::previous(). QSqlQuery::prev() осталась, но она только вызывает previous(). QSqlQuery больше не имеет каких-либо виртуальных методов, т.е., exec(), value(), seek(), next(), prev(), first(), last() и деструктор больше не являются виртуальными.
QSqlRecord теперь ведет себя как вектор, QSqlRecord::insert() фактически будет вставлять новое поле вместо замены существующего.
Класс QSqlRecordInfo был перемещен в Qt3Support. Его функциональность теперь предоставляется классом QSqlRecord.
Обзор новых классов SQL смотрите в Модуле QtSql.
Класс QSqlSelectCursor был переименован в Q3SqlSelectCursor и перемещен в библиотеку Qt3Support.
Обзор новых классов SQL смотрите в Модуле QtSql.
Класс QStoredDrag был переименован в Q3StoredDrag и перемещен в библиотеку Qt3Support. В Qt 4 используйте взамен QMimeData и вызовите QMimeData::setData() для установки данных.
Смотрите Портирование на Qt 4 - Перетаскивание для сравнения API перетаскивания в Qt 3 и Qt 4.
Вспомогательные классы QStrList и QStrIList устарели начиная с Qt 2.0. В Qt 4 они были перемещены в библиотеку Qt3Support. Если вы использовали какой-либо из них, мы рекомендуем вам использовать взамен QStringList или QList<QByteArray>.
Вспомогательные классы QStrVec и QStrIVec устарели начиная с Qt 2.0. В Qt 4 они были перемещены в Qt3Support. Если вы использовали какой-либо из них, мы рекомендуем вам использовать взамен QStringList или QList<QByteArray>.
Вот основные известные проблемы, о которых нужно знать при портировании QString на Qt 4:
Например, если у вас есть код
str1 = QString::null; if (str2 == QString::null) do_something(QString::null);
вы можете записать его в виде
str1.clear(); if (str2.isNull()) do_something(QString());
В новом коде мы рекомендуем чтобы вы не опирались на отличие между нулевой строкой и (ненулевой) пустой строкой. За подробностями обращайтесь к статье Различие между null и пустой строкой.
Чтобы получить указатель const char * на данные в кодировке ASCII или Latin-1, используйте QString::toAscii() или QString::toLatin1() чтобы получить QByteArray, содержащий данные, которые вызывает QByteArray::constData() для доступа к символьным данным непосредственно. Обратите внимание на то, что указатель, возвращаемый функцией, является допустимым только на время жизни байтового массива; вы должны избегать получения указателя на данные, содержащиеся во временных объектах.
QString greeting = "Hello"; const char *badData = greeting.toAscii().constData(); // ошибочные данные QByteArray asciiData = greeting.toAscii(); const char *goodData = asciiData.constData();
В вышеприведенном примере, указатель goodData является действенным на время жизни байтового массива asciiData. Если вам нужно сохранить копию данных в структуре данных не из Qt, используйте стандартное выделение памяти C и функции копирования строки чтобы сделать так до разрушения байтового массива.
str.at(0) = 'X';
больше не компилируется. Вместо этого используйте QString::operator[]:
str[0] = 'X';
Например, если у вас есть код
if (url.startsWith("http:", false)) ...
вы можете записать его в виде
if (url.startsWith("http:", Qt::CaseInsensitive)) ...
Например, если у вас есть код
str.setExpand(32, '$');
вы можете записать его в виде
str[32] = '$';
QStringList теперь наследуется от QList<QString> и больше не может быть конвертирован в QValueList<QString>. Так как QValueList унаследован от QList приведение типа будет работать как ожидалось.
Это изменение подразумевает некоторые несовместимости в API для QStringList. Например, at() возвращает строку, а не итератор. За подробностями обращайтесь к разделу в QValueList.
Статическая функция QStringList::split() для разделения строк на списки меньших строк была заменена на QString::split(), которая возвращает QStringList.
API класса 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 и QStyleSheetItem были переименованы в Q3StyleSheet и Q3StyleSheetItem, соответственно, и были перемещены в библиотеку Qt3Support.
Обзор классов форматированного текста Qt 4 смотрите в Обработке форматированного текста, а описание поддержки CSS-подобных таблиц стилей в Qt 4.2 и старше - в Таблицах стилей Qt.
Класс QSyntaxHighlighter из Qt 3 был переименован в Q3SyntaxHighlighter и перемещен в библиотеку Qt3Support. Начиная с Qt 4.1 его заменил новый класс QSyntaxHighlighter, базирующийся на новом механизме форматированного текста Qt 4.
Смотрите в Свойствах список свойств QTabBar в Qt 3, которые изменились в Qt 4.
Класс QTabDialog больше не является частью открытого Qt API. Он был переименован в Q3TabDialog и перемещен в Qt3Support. В приложениях Qt 4 вы можете легко получить тот же результат сочетая QTabWidget c QDialog и предоставив сами объекты QPushButton.
Смотрите также пример dialogs/tabdialog, который показывает как реализовать диалоги со вкладками в Qt 4.
Смотрите в Свойствах список свойств QTabWidget в Qt 3, которые изменились в Qt 4.
Классы QTable, QTableItem, QComboTableItem, QCheckTableItem и QTableSelection были переименованы в Q3Table, Q3TableItem, Q3ComboTableItem, Q3CheckTableItem и Q3TableSelection, соответственно, и перемещены в библиотеку Qt3Support. Новые приложения Qt должны использовать взамен новый класс QTableWidget или QTableView.
Некоторые из этих классов ведут себя по-другому по сравнению с использование обработки указателей NULL. Например, Q3TableItem::setPixmap() больше не принимает NULL или 0 чтобы указать, что элемент должен содержать нулевое растровое изображение; в этом случае нулевое растровое изображение должно быть создано и передано явно в функцию.
Обзор новых классов представления элементов смотрите в Программирование модель/представление.
Функции loadCharmap() и loadCharmapFromFile() больше не доступны в Qt 4. Вам нужно создать ваш собственный кодек, если вы хотите создать кодек основанный на описании таблицы кодов символов POSIX2.
Класс QTextDrag был переименован в Q3TextDrag и перемещен в библиотеку Qt3Support. В Qt 4 используйте взамен QMimeData и вызовите QMimeData::setText() для установки данных.
Смотрите Портирование на Qt 4 - Перетаскивание для сравнения API перетаскивания в Qt 3 и Qt 4.
Старые классы QTextEdit и QTextBrowser были переименованы в Q3TextEdit и Q3TextBrowser, соответственно, и перемещены в Qt3Support. Новые классы QTextEdit и QTextBrowser имеют немного другой API.
Функция QTextEdit::setWrapPolicy() была переименована в setWordWrapMode(), а функция QTextEdit::setWrapColumnOrWidth() была переименована в setLineWrapColumnOrWidth(). Функции Q3TextEdit::setWrapPolicy() и Q3TextEdit::setWrapColumnOrWidth() предоставляют эту функциональность в классе Q3TextEdit.
Обзор классов форматированного текста Qt 4 смотрите в Обработке форматированного текста.
Вспомогательный класс QTextIStream больше не предоставляется в Qt 4. Используйте вместо нее непосредственно QTextStream.
Вспомогательный класс QTextOStream больше не предоставляется в Qt 4. Используйте вместо нее непосредственно QTextStream.
Недокументированный класс QTextOStreamIterator был удален из библиотеки Qt. Если он необходим в вашем приложении, просто скопируйте исходный код из заголовочного файла <qtl.h> Qt 3.
В QTextStream некоторому улучшению подвергся API и реализация, а некоторые изменения повлияли на поведение QTextStream'а:
Обратите внимание на то, что в Qt 4 при использовании QTextStream на QFile, вызов QIODevice::reset() на QFile не будет иметь ожидаемого результата, поскольку QTextStream теперь буферизует файл. Вместо этого используйте функцию QTextStream::seek().
Класс QTextView был переименован в Q3TextView и перемещен в библиотеку Qt3Support.
Класс QTimeEdit в Qt 4 является вспомогательным классом, базирующимся на QDateTimeEdit. Старый класс был переименован в Q3TimeEdit и перемещен в библиотеку Qt3Support.
Смотрите в Виртуальных функциях список виртуальных функций-членов QTimeEdit в Qt 3, которые больше не являются виртуальными в Qt 4.
Windows ограничивает точность таймеров, но начиная с Qt 4, мы эмулируем точное временное разрешение. В Windows XP мы используем API мультимедийного таймера, который дает разрешение в 1 миллисекунду для QTimer.
Обратите внимание на то, что другие версии Windows имеют меньшее временное разрешение, и что код, зависящий от базовой системы ограничения таймера, не сталкивается с такими ограничениями при использовании Qt 4 (например, установка интервала в 0 миллисекунд приведет в Qt к завладению всем процессорным временем когда не нужно обрабатывать никаких событий ГПИ).
Старый класс QToolBar, который работал со старыми классами QMainWindow и QDockArea и унаследован от QDockWindow, был переименован в Q3ToolBar и перемещен в Qt3Support. Обратите внимание на то, что, когда используется Q3ToolBar, действия панели инструментов должны быть объектами Q3Action.
В новых приложениях используйте новый класс QToolBar.
Замечание: Свойство Q3ToolBar'а, horizontallyStretchable, может быть достигнуто в QToolBar с помощью политик размера.
Смотрите в Свойствах список свойств QToolButton в Qt 3, которые изменились в Qt 4.
Обратите внимание на то, что многие свойства, которые могут быть предварительно установлены в конструкторе должны теперь устанавливаться раздельно.
Функции QToolTip::setGloballyEnabled() больше нет. Всплывающие подсказки могут быть отключены установкой фильтра событий на qApp (уникальный объект QApplication) для блокирования событий типа QEvent::ToolTip.
Класс QUriDrag был переименован в Q3UriDrag и перемещен в библиотеку Qt3Support. В Qt 4 используйте взамен QMimeData и вызовите QMimeData::setUrl() для установки URL.
Смотрите Портирование на Qt 4 - Перетаскивание для сравнения API перетаскивания в Qt 3 и Qt 4.
Класс QUrl был переписан с нуля в Qt 4 чтобы быть более соответствующим стандарту. Старый класс QUrl был переименован в Q3Url и перемещен в библиотеку Qt3Support.
Новый класс QUrl предоставляет исчерпывающий список функций совместимости для облегчения портирования с Q3Url на QUrl. Новые функции требуют изменить ваш код:
Класс QUrlOperator больше не является частью открытого Qt API. Он был переименован в Q3UrlOperator и перемещен в Qt3Support.
Начиная с Qt 4.4 Network Access API предоставляет подмножество возможностей, предоставляемых QUrlOperator, которые предназначены в основном для использования с приложениями, которые используют протоколы HTTP и FTP. Подробности смотрите в документации к QNetworkRequest, QNetworkReply и QNetworkAccessManager.
Класс 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, основанный на итераторах.
Вот список проблемных функций:
Например, если у вас есть код
for (QValueList<T>::iterator i = list.fromLast(); i != list.begin(); --i) do_something(*i);
вы можете записать его в виде
QLinkedList<T>::iterator i = list.end();
while (i != list.begin()) {
--i; // уменьшаем i на 1 перед использованием
do_something(*i);
}
Класс QValueVector<T> был заменен классом QVector<T> в Qt 4. В качестве помощи при портировании старых приложений Qt, библиотека Qt3Support содержит класс Q3ValueVector<T>, реализованный на основе нового класса QVector<T>.
При портировании с QValueVector<T> на QVector<T>, вы можете столкнуться со следующими несовместимостями:
Обзор контейнерных классов Qt 4 смотрите в Базовые контейнеры.
Некоторые изменения в остальной части библиотеки 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().
Функция в Qt 3 | Функция в Qt 4 |
---|---|
toBitmap () | QVariant::value() |
toBrush () | QVariant::value() |
toColorGroup () | Вместо этого используйте QVariant::value() вместе с QPalette. |
toColor () | QVariant::value() |
toCString () | QVariant::toByteArray() |
toCursor () | QVariant::value() |
toFont () | QVariant::value() |
toIconSet () | Вместо этого используйте QVariant::value() вместе с QIcon. |
toImage () | QVariant::value() |
toKeySequence () | QVariant::value() |
toPalette () | QVariant::value() |
toPen () | QVariant::value() |
toPixmap () | QVariant::value() |
toPointArray () | QVariant::value() |
toRegion () | QVariant::value() |
toSizePolicy () | QVariant::value() |
Смотрите в перечислении QVariant::Type список типов, поддерживаемых QVariant.
Класс 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 был переименован в Q3VGroupBox и перемещен в библиотеку Qt3Support. Qt 4 не предоставляет конкретного класса замены для QVBoxLayout поскольку QGroupBox спроектирован виджетом обобщенного контейнера. В результате, вам нужно обеспечить вашу собственную компоновку для любых дочерних виджетов.
Для получения дополнительной информации о портировании кода, который использует групповые рамки, смотрите #QGroupBox.
Класс QWhatsThis был перепроектирован в Qt 4. Старый класс QWhatsThis доступен как Q3WhatsThis в Qt3Support.
Отрисовка фона виджета была значительно улучшена, поддерживая обновления без мерцания и делая возможным получение полупрозрачных виджетов. Это приводит к тому, что следующие функции обработки фона устарели:
Код примера того, как в 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 был заменен классом QFormBuilder в Qt 4.
Класс QWidgetIntDict был синонимом для QIntDict<QWidget>. В Qt 4 он больше не доступен. Если вы скомпоновали вместе с Qt3Support, вы можете использовать взамен Q3IntDict<QWidget>; в противном случае, смотрите раздел в QDict<T>.
В Qt 3 класс QWidgetList был псевдонимом (typedef) для QPtrList<QWidget>. В Qt 4 он является псевдонимом (typedef) для QList<QWidget *>. Смотрите раздел в QPtrList<T>.
Класс QWidgetPlugin более не доступен в Qt 4. Чтобы создать пользовательские подключаемые модули виджета, создайте подкласс QDesignerCustomWidgetInterface для предоставления информации о пользовательском виджете, и собрать подключаемый модуль способом, описанным в примере Пользовательский подключаемый модуль виджета.
Класс QWidgetStack больше не является частью открытого Qt API. Он был переименован в Q3WidgetStack и перемещен в Qt3Support. В приложениях Qt 4 вы можете использовать вместо него QStackedWidget чтобы получить такие же результаты.
Класс QWizard был перепроектирован в Qt 4.3. За подробностями обращайтесь к Примеру "Trivial Wizard", Примеру "License Wizard" и Примеру "Class Wizard".
Класс QWorkspace в Qt 4 требует явного добавления окон MDI с помощью QWorkspace::addWindow().
[Предыдущая: Руководства по портированию] [Содержание] [Следующая: Переход на Qt 4 - виртуальные функции]
Авторские права © 2010 Nokia Corporation и/или её дочерние компании | Торговые марки | Qt 4.6.4 |
Попытка перевода Qt документации. Если есть желание присоединиться, или если есть замечания или пожелания, то заходите на форум: Перевод Qt документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |