Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: evilguard от Апрель 27, 2007, 08:42



Название: Изменение размеров графического элемента.
Отправлено: evilguard от Апрель 27, 2007, 08:42
Обычно во всяких графических программах, например в том же самом paint при выделении какой-то области в углах и на сторонах выделенного прямоугольника появляются квадратики, двигая которые можно изменять размер выделенного участка. Хочу то же самое сделать для своих graphicsitem в программе. Только не знаю как лучше сделать это.
Есть такие соображения - квадратики сделать дочерними по отношению к graphicsitem, они сами должныы быть потомками QGraphicsItem. Далее - их поведение должно ведь различаться в зависимости от того какой это квадратик - topLeft, topRight, bottomLeft, bottomRight. То есть мне создавать 4 класса чтоли?
Код:

// Классы квадратиков

class TopLeftSquare : public QGraphicsRectItem
{
.... // поведение
}

class TopRightSquare : public QGraphicsRectItem
{
....
}

class BottomLeftSquare : public QGraphicsRectItem
{
....
}

class BottomRightSquare : public QGraphicsRectItem
{
....
}

struct AllSquares
{
  AllSquares (MyGraphicsItem *parent);

private:
  TopLeftSquare        *m_topLeft;
  TopRightSquare      *m_topRight;
  BottomLeftSquare   *m_bottomLeft;
  BottomRightSquare *m_bottomRight;
}

class MyGraphicsItem : public QGraphicsItem
{
private:
  AllSquares sizeChangers;
}


Помогите с идеологией в общем, как правильнее организовать этот кусок кода?


Название: Изменение размеров графического элемента.
Отправлено: Kosh от Апрель 27, 2007, 09:28
А , может, всё-таки один класс а способ поведения задавать функцией , ну, чем-то вроде

setBehavier( BottomLeft );

добавлено спустя 8 минут:

 Я вот тут подумала, а разве их поведение разное? Ты нажимаешь на любой мышкой, тащишь и отпускаешь.

У тебя должен быть класс, который содержит в себе выделенную область, рисует рамочку и эти квадратики, уж если тебе так хочется их завести. Этот класс должен по ходу перетаскивания получать от захваченного квадратика его координаты и его тип (BottomLeft, например) и в зависимости от типа правильно перерисовать свое содержимое. Я бы вообще не стала заморачиваться на эти квадратики, как отдельные элементы, а просто бы отрисовывала бы их как часть рамки


Название: Изменение размеров графического элемента.
Отправлено: evilguard от Апрель 27, 2007, 10:12
Спасибо за советы, так действительно проще как ты предложила. Почему хочу сделать эти квадратики, как отдельные элементы - так проще будет их перемещать, обрабатывать mouse-over (чтобы изменять курсор).


Название: Изменение размеров графического элемента.
Отправлено: Kosh от Апрель 27, 2007, 11:04
так и в моём варианте курсор менять не сложнее. В обработчике мыши проверяешь, не заехал ли курсор в одну из зон для перетаскивания, и если да - взводишь какой-нибудь флажок, меняешь курсор; выехал - курсор обратно, флажок сбросил. А когда мышка нажата, только отрисовываешь рамку. Нафига для таких мелочей городить кучу потомков.

Обрати внимание, что при перемещении одного из квадратиков, тебе прийдется перемещать еще и двух его соседей.


Название: Изменение размеров графического элемента.
Отправлено: evilguard от Апрель 27, 2007, 11:17
дело еще в том, что квадратики должны быть за пределами области. А рисование в QGraphicsItem за пределами boundingRect некорректно.


Название: Изменение размеров графического элемента.
Отправлено: Kosh от Апрель 27, 2007, 12:00
А кто мешает охватить областью и квадратики? А область перерисовки внутри чуть меньших размеров

http://picasaweb.google.com/lh/viewPhoto?uname=elkina.anna&aid=5057996592902498641&iid=5057997679529224546


Название: Изменение размеров графического элемента.
Отправлено: evilguard от Апрель 27, 2007, 12:37
я так и делаю (пока просто рисую квадратики и охватываю областью). Но тогда получается, что мне надо будет отдельно обрабатывать перемещение item'а - то есть так, чтобы он перемещался при нажатии только по области перерисовки. Ведь за областью перерисовки есть "полоски" между квадратиками, которые входят в graphicsitem, но по логике программы не должны к нему относится(то есть если щелкаешь по ним выделение должно сниматься)


Название: Изменение размеров графического элемента.
Отправлено: Kosh от Апрель 27, 2007, 13:54
Что-то ты мудришь. Давай по порядку:

1 у тебя есть виджет, размеры которого тебе надо менять. Его хозяин какой-то большой виджет - Стол

2 По щелчку на этой кнопке ты создаешь свой виджет, назовем его ВыделеннаяОбласть. Его размеры равны размерам кнопки + ширина рамки (которая состоит из черных квадратиков и "пустых" прямоугольников).  Стол становится хозяином ВыделеннойОбласти, а ВыделеннаяОбласть становится хозяином редактируемой кнопки.

3 ВыделеннаяОбласть отслеживает движение мыши и нажатия.

- а. наехали на черный квадратик - меняем курсор
- б. нажали на черный квадратик - включаем режим растягивания (например, взводим флажок (обожаю флажки!) Моде)
- в. пока Моде взведен растягиваем свои размеры и рисуем резиновую рамку или сразу растягиваем кнопку
- г. мышь отпустили - сбрасываем флажок , растягиваем кнопку до новых размеров.
- д. если щелчок мыши на "пустом" прямоугольнике, делаем то же, что и при смене фокуса (как вариант - "выкидываем" из ВыделеннойОбласти кнопку, а Выделенную область гасим или вообще удаляем, это как тебе захочется.) Стол становится опять хозяином изменённой кнопки.

добавлено спустя 15 минут:

 Ты, случайно, не диплом пишешь?

добавлено спустя:

 Если есть свободное время, почему бы не ковырнуть дизайнер, как у него это сделано?


Название: Изменение размеров графического элемента.
Отправлено: evilguard от Апрель 27, 2007, 14:36
не виджет, а QGraphicsItem! Просто области между угловыми квадратиками не должны входить в эту область. Ну ладно спасибо за советы! С учетом их я уже понял как правильно сделать. Действительно плодить отдельные элементы для квадратиков смысла нет.

добавлено спустя 34 минуты:

 Диплом не пишу:) Пытаюсь написать альтернативу коммерческой софтине :)


Название: Изменение размеров графического элемента.
Отправлено: Kosh от Апрель 27, 2007, 14:52
Цитата: "evilguard"

 Пытаюсь написать альтернативу коммерческой софтине :)


Похоже, эдесь половина народа этим занимается  :D


Название: Изменение размеров графического элемента.
Отправлено: evilguard от Апрель 27, 2007, 15:05
Что-то не нашел как переопределить для QGraphicsItem действие, когда мышка по нему водишь мышью. Есть mouseMoveEvent ( QGraphicsSceneMouseEvent * event ) - но оно срабатывает только тогда, когда нажата кнопка мыши. А мне нужно просто поменять курсор, когда он будет над этими квадратиками.


Название: Изменение размеров графического элемента.
Отправлено: bigirbis от Апрель 27, 2007, 15:31
void QGraphicsItem::hoverMoveEvent ( QGraphicsSceneHoverEvent * event )  [virtual protected]
и еже с ним не покатят?


Название: Изменение размеров графического элемента.
Отправлено: evilguard от Апрель 28, 2007, 07:21
пробовал hoverMoveEvent - не катит почему-то.

добавлено спустя 1 час 7 минут:

 Вроде то что нужно этот hoverMoveEvent - но не работает почему-то:
Код:

void hoverMoveEvent ( QGraphicsSceneHoverEvent * event )
{
setCursor( QCursor(Qt::PointingHandCursor) );
}

Ноль реакции дебаггером проверял не заходит даже в эту функцию

добавлено спустя 14 часов 38 минут:

 Оказывается есть такая замечательная функция - void QGraphicsItem::setAcceptsHoverEvents ( bool enabled ). А по умолчанию элементы не получают событий связанных с наездом мыши.