[Предыдущая: Портирование файлов UI на Qt 4] [Содержание] [Следующая: qt3to4 - Инструмент перехода с Qt 3 на 4] Переход на графическое представление
|
Q3Canvas | QGraphicsScene |
---|---|
Q3Canvas::Q3Canvas() | Больше нет конструктора, основанного наQPixmap, и концепция пластин пропала. Вы можете использовать QGraphicsScene::backgroundBrush для установки шаблона фона или переопределить QGraphicsScene::drawBackground() в подклассе QGraphicsScene (смотрите Перевод сцен с пластинами). В дополнение, геометрия QGraphicsScene предоставляется в виде полного QRectF. Вместо Q3Canvas(int width, int height), вы можете использовать QGraphicsScene(int top, int left, int width, int height). |
Q3Canvas::allItems() | QGraphicsScene::items() возвращает список всех объектов на сцене. |
Q3Canvas::backgroundColor() | Вы можете назначить цвет для фона с помощью свойств QGraphicsScene::backgroundBrush или QGraphicsView::backgroundBrush. |
Q3Canvas::backgroundPixmap() | Вы можете установить растровое изображение пластины для фона с помощью QGraphicsScene::backgroundBrush или QGraphicsView::backgroundBrush. Для большего контроля за позиционированием изображения, вы можете переопределить QGraphicsScene::drawBackground() или QGraphicsView::drawBackground(). |
Q3Canvas::chunkSize() | Ближайшим эквивалентом размеру кусков в Q3Canvas является глубина BSP-дерева QGraphicsScene. QGraphicsScene назначает глубину автоматически, и размер каждого сегмента сцена зависит от этой глубины и QGraphicsScene::sceneRect(). Смотрите QGraphicsScene::itemIndexMethod. |
Q3Canvas::collisions() | QGraphicsScene предоставляет несколько способов для обнаружения столкновений элементов. ПерегруженнаяQGraphicsScene::items() возвращает элементы которые столкнулись с точкой, прямоугольником, полигоном или произвольным путём векторов (QPainterPath). Вы можете также вызывать QGraphicsScene::collidingItems() для определения столкновений с элементом. |
Q3Canvas::drawArea() | Функция QGraphicsScene::render() предоставляет оригинальное поведение Q3Canvas::drawArea(). Дополнительно вы можете передать прямоугольник источника для отрисовки только части сцены и прямоугольник приёмника для отрисовки на указанную область целевого устройства. QGraphicsScene::render() дополнительно может преобразовать исходный прямоугольник так, чтобы он разместился в целевом прямоугольнике. Смотрите Печать |
Q3Canvas::onCanvas() | В графическом представлении нет эквивалента данной функции. Тем не менее вы можете скомбинировать QGraphicsScene::sceneRect() и QRectF::intersects():item->scene().sceneRect().intersects(item->sceneBoundingRect()); |
Q3Canvas::rect() | Его эквивалент QGraphicsScene::sceneRect() возвращает QRectF (координаты двойной точности). Его верхний левый угол может иметь произвольные координаты (Q3Canvas::rect().topLeft() всегда (0, 0)). |
Q3Canvas::resize() | Вместо него вы можете вызвать QGraphicsScene::setSceneRect(0, 0, width, height). |
Q3Canvas::retune() | Смотрите QGraphicsScene::itemIndexMethod. Вы можете настроить индексирование установкой подходящего sceneRect(). Оптимальная глубина BSP-дерева QGraphicsScene определяется автоматически. |
Q3Canvas::setAdvancePeriod() | В новом API нет концепции предварительного периода; вместо этого вы можете соединить QTimer::timeout() со слотом QGraphicsScene::advance() чтобы получить похожую функциональность. Это будет приводить к вызову функции QGraphicsItem::advance() всех элементов. Смотрите также QGraphicsItemAnimation. |
Q3Canvas::setAllChanged() | Вы можете вызвать QGraphicsScene::update() без аргументов. |
Q3Canvas::setChanged() | QGraphicsScene::update() вызывет перерисовку всей сцены или её частей. |
Q3Canvas::setDoubleBuffering() | Двойной буфер Q3Canvas' позволяет кэшировать содержимое сцены в координатах устройства (т.е., области просмотра). Вместо этого данный слой кэша был перемещён в вид; вы можете кэшировать фон QGraphicsScene с помощью QGraphicsView::setCacheMode(). QGraphicsView::resetCachedContent() перезагрузит области кэша, которые изменились. |
Q3Canvas::tile() | Смотрите Перевод сцен с плитками. |
Q3Canvas::setTiles() | Смотрите Перевод сцен с плитками. |
Q3Canvas::setUnchanged() | В графическом представлении ему нет эквивалента. Обычно этот вызов может быть вызван без побочных эффектов. |
Q3Canvas::setUpdatePeriod() | В новом API нет концепции периода обновления; вместо этого вы можете соединить QTimer::timeout() со слотом QGraphicsScene::update() чтобы получить похожую функциональность. Смотрите также QGraphicsItemAnimation. |
Q3Canvas::size() | QGraphicsScene::sceneRect().size() возвращает QSizeF, с двойной точностью координат. |
Q3Canvas::validChunk() | Чтобы определить находится ли область внутри сцены или нет, вы можете скомбинировать QRectF::intersects() с QGraphicsScene::sceneRect(). |
Q3Canvas::resized() | QGraphicsScene вырабатывает sceneRectChanged() когда изменяется прямоугольник сцены. |
Q3Canvas::drawBackground() | Вы можете переопределить QGraphicsScene::drawBackground() чтобы отрисовывать фон сцены. Вы также можете переопределить QGraphicsView::drawBackground() чтобы заменить этот фон если вам нужны разные фоны в разных видах. |
Q3Canvas::drawForeground() | Вы можете переопределить QGraphicsScene::drawForeground() чтобы отрисовывать передний план сцены. Вы можете также переопределить QGraphicsView::drawForeground() чтобы заменить этот передний план если вам нужны различные передние планы для разных видов. |
QGraphicsScene не предоставляет API для плиток. Тем не менее, вы можете получить похожее поведение отрисовывая растровые изображения в переопределённой функции QGraphicsScene::drawBackground().
Поддержка плиток Q3Canvas основана на предоставлении одного растрового изображения, содержащего плитки фиксированной ширины и высоты, и затем доступа к ним (чтение и замена пластин) по индексу. Плитки в растровом изображении упорядочены слева на право, сверху вниз.
0 | 1 | 2 | 3 |
4 | 5 | 6 | 7 |
С графическим представлением это растровое изображение может храниться как член подкласса QGraphicsScene. Три главные функции, которые составляют открытый API плиток, могут быть определены как новые члены этого класса. Вот один пример как реализовать поддержку плиток:
class TileScene : public QGraphicsScene { public: ... void setTiles(const QPixmap &pixmap, int h, int v, int tileHeight, int tileWidth); void setTile(int x, int y, int tilenum); private: QRect tileRect(int x, int y) const; QRect tileRect(int tileNum) const; QVector<QVector<int> > tiles; QPixmap tilePixmap; int tileW, tileH; int hTiles, vTiles; };
В зависимости от того как ваша сцена использует пластины, вы можете упростить этот подход. В данном примере мы попробуем воспроизвести поведение функций Q3Canvas.
Мы начинаем с создания подкласса QGraphicsScene ("TileScene"). В этом классе мы декларируем две функции для работы с плитками из Q3Canvas, а затем мы добавляем две вспомогательные функции, которые возвращают прямоугольник для определённой плитки в нашем растровом изображении плиток. Мы будем использовать двухмерный вектор целых чисел чтобы отслеживать какие плитки должны быть использованы на какой части сцены.
void TileScene::setTiles(const QPixmap &pixmap, int h, int v, int tileHeight, int tileWidth) { tilePixmap = pixmap; tileW = tileWidth; tileH = tileHeight; hTiles = h; vTiles = v; tiles.resize(v); for (int y = 0; y < v; ++y) tiles[y].resize(h); }
В setTiles() мы сохраняем растровое изображение и свойства плитки как члены класса. Затем мы изменяем размер вектора плиток чтобы он совпадал с шириной и высотой нашей сетки пластин.
void TileScene::setTile(int x, int y, int tilenum) { tiles[y][x] = tilenum; update(tileRect(x, y)); }
Функция setTile() обновляет индекс плиток и затем обновляет соответствующий прямоугольник на сцене, вызывая tileRect().
QRect TileScene::tileRect(int x, int y) const { return QRect(x * tileW, y * tileH, tileW, tileH); }
Первая функция tileRect() возвращает QRect для плитки на позиции (x, y).
QRect TileScene::tileRect(int tileNum) const { int numHTiles = tilePixmap.width() / tileW; int numVTiles = tilePixmap.height() / tileH; return tileRect(tileNum % numHTiles, tileNum / numHTiles); }
Вторая функция tileRect() возвращает QRect для номера плитки. С этими функциями мы можем реализовать функцию drawBackground().
void drawBackground(QPainter *painter, const QRectF &exposed) { for (int y = 0; y < vTiles; ++y) { for (int x = 0; x < hTiles; ++x) { QRect destRect = tileRect(x, y); if (exposed.intersects(destRect)) { painter->drawPixmap(destRect, tilePixmap, tileRect(tiles[y][x])); } } } }
В drawBackground(), мы перерисовываем все плитки, прямоугольники которых пересекаются с отображаемой области фона.
Ближайший эквивалент для Q3CanvasView в графическом представлении называется QGraphicsView. В большинстве случаев это простейший класс для перевода. В дополнение ко всей предоставляемой функциональности Q3CanvasView, QGraphicsView включает некоторые новые полезные особенности. Вы можете прочитать об этом больше в документации по QGraphicsView.
QGraphicsView может кэшировать видимое содержимое сцены, аналогично тому как Q3Canvas::setDoubleBuffering() может кэшировать все содержимое сцены. Вы можете вызвать QGraphicsView::setCacheMode() для настройки кэширования и QGraphicsView::resetCachedContent() аннулирует кэш.
Для улучшенной поддержки навигации вы можете установить якорь изменения размера или преобразования с помощью QGraphicsView::resizeAnchor и QGraphicsView::transformationAnchor. Это позволит вам легко поворачивать и масштабировать вид зафиксировав центр или мастабировать относительно позиции под курсором мыши. Также, если вы установите QGraphicsView::dragMode для вида, QGraphicsView предоставит выделение резиновой нитью или навигацию "нажми-и-тяни" с использованием курсоров OpenHandCursor и ClosedHandCursor.
Ближайшим эквивалентом для Q3CanvasItem в графическом представлении называется QGraphicsItem. Наследование от этого класса является обычной практикой, поэтому перевод Q3CanvasItem часто требует больше работы чем Q3Canvas и Q3CanvasView.
Q3CanvasItem стал проще для использования, проще для наследования и более мощным с QGraphicsItem. Ключевым отличаем от Q3CanvasItem заключается в продвижении событий и группах элементов, но вы также найдёте несколько новых удобных особенностей, таких как поддержка всплывающих подсказок, курсоров, трансформации элементов и перетаскивания. Вы можете прочитать всё о QGraphicsItem в его собственной документации.
Эта секция начинается с таблицы, которая показывает как перевести каждую функцию с Q3CanvasItem на QGraphicsItem. Сразу после этого, каждый стандартный подкласс Q3CanvasItem имеет собственную секцию.
Обратите внимание на то, что некоторые виртуальные функции, которые передавались в QGraphicsItem, перестали быть виртуальными. Пример - Q3CanvasItem::moveBy(), которая часто использовалась для отслеживания перемещения элементов. В этом случае виртуальная функция QGraphicsItem::itemChange() перенимается как замена.
Ближайший эквивалент для Q3CanvasPolygonalItem в графическом представлении называется QAbstractGraphicsShapeItem. В отличае от Q3CanvasPolygonalItem, он не определяет точки области (Q3CanvasPolygonalItem::areaPoints()); вместо этого геометрия каждого элемента хранится в качестве члена подклассов.
Функция Q3CanvasPolygonalItem::drawShape() больше не доступна; вместо неё вы можете установить перо и карандаш из QGraphicsItem::paint().
Q3CanvasPolygonalItem | QAbstractGraphicsShapeItem |
---|---|
Q3CanvasPolygonalItem::areaPoints() | вместо этого геометрия каждого элемента хранится в качестве члена соответствующего подкласса. |
Q3CanvasPolygonalItem::areaPointsAdvanced() | Нет эквивалента; вы можете взамен использовать QPolygonF::translate() или QPainterPath::translate(). |
Q3CanvasPolygonalItem::drawShape() | QGraphicsItem::paint(). Вы можете установить карандаш и перо внутри данной функции. |
Q3CanvasPolygonalItem::invalidate() | Вызывайте QGraphicsItem::prepareGeometryChange() перед изменением геометрии элемента. |
Q3CanvasPolygonalItem::isValid() | Нет эквивалента; геометрия элемента всегда в годном состоянии. |
Q3CanvasPolygonalItem::winding() | Эта функция полезна только для элементов полигонов и путей; смотрите QGraphicsPolygonItem::fillRule(), и QPainterPath::fillRule() для QGraphicsPathItem. |
Ближайший эквивалент для Q3CanvasEllipse в графическом представлении называется QGraphicsEllipseItem. Наиболее заметное отличие от QGraphicsEllipseItem в том, что эллипс больше не отрисовывается с центром в его позиции; вместо этого он рисуется ограниченным QRectF также как QPainter::drawEllipse().
Для совместимости вы можете сдвинуть эллипс вверх и влево чтобы сохранить эллипс отцентрированным. Пример:
// Прежде Q3CanvasEllipse ellipse(10, 10); // После QGraphicsEllipseItem ellipse(-5, -5, 10, 10);
Замечание: QGraphicsEllipseItem использует QAbstractGraphicsShapeItem::pen() для внешних линий там, где Q3CanvasEllipse не использует Q3CanvasPolygonalItem::pen().
Ближайший эквивалент для Q3CanvasLine в графическом представлении называется QGraphicsLineItem.
Ближайший эквивалент для Q3CanvasPolygon в графическом представлении называется QGraphicsPolygonItem.
Ближайший эквивалент для Q3CanvasSpline в графическом представлении называется QGraphicsPathItem. Этот элемент может быть использован для описания любого типа пути, поддерживаемого QPainter.
Q3CanvasSpline берёт свои контрольные точки в качестве Q3PointArray, но QPainterPath оперирует последовательностью вызовов QPainterPath::moveTo() и QPainterPath::cubicTo(). Вот как вы можете преобразовать кривую Безье Q3PointArray в QPainterPath:
static QPainterPath fromControlPoints(const Q3PointArray &pa) { QPainterPath path; path.moveTo(pa[0]); for (int i = 1; i < pa.size(); i += 3) path.cubicTo(pa[i], pa[(i + 1) % pa.size()], pa[(i + 2) % pa.size()]); return path; }
Замечание: QGraphicsPathItem использует QAbstractGraphicsShapeItem::pen() для внешних линий там, где Q3CanvasSpline не использует Q3CanvasPolygonalItem::pen().
Q3CanvasSpline | QGraphicsPathItem |
---|---|
Q3CanvasSpline::closed() | Нет эквивалента Вы можете вызвать QPainterPath::closeSubPath() чтобы явно закрыть путь. |
Ближайший эквивалент для Q3CanvasRectangle в графическом представлении называется QGraphicsRectItem.
Q3CanvasSprite это класс элемента, которые в наибольшей степени отличается от своего предшественника Q3Canvas. Ближайшим подобием Q3CanvasSprite в графическом представлении является QGraphicsPixmapItem.
Q3CanvasSprite поддерживает анимированные растровые изображения; тем не менее QGraphicsPixmapItem является элементом с простым однокадровым растровым изображением. Если всё что вам нужно это растровое изображение, то переход является простым. Если вам требуется поддержка анимации, то потребуется дополнительная работа; в данном случае нет прямого подхода для перехода.
Для примера Пример "Ported Asteroids" используется подкласс QGraphicsPixmapItem для замещения Q3CanvasSprite, храня список изображений и счётчик кадров. Анимация происходит в QGraphicsItem::advance().
Эти классы были убраны из API. Вы можете использовать QPixmap вместо Q3CanvasPixmap и QList вместо Q3CanvasPixmapArray.
Q3CanvasPixmapArray обеспечивает удобство для загрузки последовательности изображений или масок с использованием пути с подстановочными знаками (смотрите Q3CanvasPixmapArray::readPixmaps() и Q3CanvasPixmapArray::readCollisionMasks()). Чтобы добиться похожей функциональности с использованием графического представления, вы можете загружать изображения с использованием QDir:
wildcardPath.replace("%1", "*"); QFileInfo fi(wildcardPath); QList<QPixmap> frames; foreach (QString entry, QDir(fi.path(), fi.fileName()).entryList()) frames << QPixmap(fi.path() + "/" + entry);
В графическом представлении Q3CanvasText был разделён на два кла: QGraphicsSimpleTextItem и QGraphicsTextItem. Для перехода вполне подходит QGraphicsSimpleTextItem. QGraphicsTextItem предоставляет дополнительные особенности структурирования документа, похожие на возможности QTextEdit, и также позволяет взаимодействие (т.е., редактирование и выделение).
Вместо этого используйте QList.
Статья Porting to Qt 4.2's Graphics View в ежеквартальнике Qt Quarterly 21 описывает процесс перевода примера канвы с Qt 3 на Qt 4. Результатом является пример Ported Canvas.
[Предыдущая: Портирование файлов UI на Qt 4] [Содержание] [Следующая: qt3to4 - Инструмент перехода с Qt 3 на 4]
Авторские права © 2010 Nokia Corporation и/или её дочерние компании | Торговые марки | Qt 4.6.4 |
Попытка перевода Qt документации. Если есть желание присоединиться, или если есть замечания или пожелания, то заходите на форум: Перевод Qt документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |