Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.71/34: Рейтинг темы: голосов - 34, средняя оценка - 4.71
161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
1

Захват, перемещение, изменение размера полигона

01.11.2016, 12:01. Показов 6427. Ответов 31
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Приветствую всех.
Подскажите пожалуйста, с какой стороны подойти к данному вопросу. Есть свой итем, наследник от QGraphicsPolygonItem. После отрисовки, не важно1 или 10 полигонов, мне надо, чтобы кликнув мыши по одному из них, произошло выделение итема, а далее его можно было бы двигать или целиком или потянув за одну из его точек. Как правильно это реализовать? Или может у кого есть ссылка на подобный проект? Буду благодарен за любую информацию.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.11.2016, 12:01
Ответы с готовыми решениями:

Перемещение и изменение размера контрола RunTime
Добрый день. Я хочу сделать для пользователя возможность перемещать контрол по форме и изменять...

Классы в Delphi + графика. Создание объектов, перемещение, изменение размера, поворот на определенный угол
У меня возникла проблема с этой задачей. Все что у меня получилось - строить фигуры по нажатию...

Изменение полигона в Gerber файле
Всем привет! Порой мне приходится делать групповые заготовки печатных плат (в распоряжении...

Изменение размера окна -> изменение размера картинки
Есть картинка на Homepage, как сделать так, что бы при изменении окна браузера размер картинки...

31
Заблокирован
08.11.2016, 12:05 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от Sph Посмотреть сообщение
либо мы не понимаем друг друга
Я тебе вроде уже говорил, что ты говоришь на каком - то странном русском
Вот ты сам пишешь:
Цитата Сообщение от Sph Посмотреть сообщение
Далее я фигуру двигаю по сцене, и при повторном нажатии, координаты вернутся те же что и первый раз.
Ну и что ты хотел? Куда бы ты айтим свой не подвинул в сцене, он тебе вернёт координаты своего локального полигона в своих локальных координатах, то есть если ты в айтиме вызываешь this->polygon(), то этот полигон в локальных координатах.
Ты как айтим двигаешь то? Ты его в сцене передвигаешь или же он у тебя на месте и двигает полигон внутри айтима?
0
161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
08.11.2016, 12:46  [ТС] 22
Цитата Сообщение от WarpDrive Посмотреть сообщение
Ну и что ты хотел?
Ну я хочу чтобы после перемещения, итем возвращал свои новые координаты вершин)
Цитата Сообщение от WarpDrive Посмотреть сообщение
он у тебя на месте и двигает полигон внутри айтима?
вот это вообще не понял
0
Заблокирован
08.11.2016, 12:48 23
Цитата Сообщение от Sph Посмотреть сообщение
Ну я хочу чтобы после перемещения, итем возвращал свои новые координаты вершин)
Ты переместил item в сцене и хочешь получить координаты его локального полигона в системе координат глобальной сцены? Если да - я уже ответил - делаешь mapToScene

Если совсем тупик - архив с кодом прикрепляй
0
161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
11.11.2016, 12:26  [ТС] 24
Подниму тему. Подскажите пожалуйста, как правильно мне передать информацию от итемов-вершин полигона, что они двигают до самого полигона, чтобы он перерисовался с новыми координатами? В классе полигона, при событиях перемещения я создаю\пересоздаю итемы-вершины(отдельный класс унаследованный от обычного qgraphicsItem). Но когда я кликаю по ним, программа крашится ссылаясь на QGraphicsItem::mousePressEvent(event);, а так же move-release в классе-вершине. Если сделать Q_UNUSED(event); то вершины передвигаются, но как вернуть сигналы до полигона, и гонять их туда-сюда?
0
184 / 176 / 57
Регистрация: 25.09.2014
Сообщений: 828
11.11.2016, 16:07 25
Сдается мне, что ты пытаешься обратиться через указатель на несуществующий элемент. Как раз таки на круглях, который ты зачем-то пересоздаешь в добавок.
Создал один раз и все. Хочешь - делай их невидимыми, если родитель не в фокусе. Но удалять-то зачем?

Сцена - итем - круглях. Где ты работаешь с перемещением? На сцене или в самом итеме? Я обычно управляю всеми итемами со сцены. Если же ты управляешь из кругляха, то когда отпускаешь кнопку, берешь event->pos(). Координаты сцены, в которых ты отпустил мышку. И эти координаты передаешь сигналом родителю - итему. Угол итема ставишь в них точно так же - через setPos(), ведь родителя у итема нет, а значит это будут координаты сцены. То, что тебе и нужно.

Либо рассказывай, чего ты там создал такое.
0
161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
14.11.2016, 08:35  [ТС] 26
Цитата Сообщение от Горбаг Посмотреть сообщение
Сдается мне, что ты пытаешься обратиться через указатель на несуществующий элемент. Как раз таки на круглях, который ты зачем-то пересоздаешь в добавок.
ну круглях есть, я проверяю это, и сцена говорит что итем то сущствует. Пересоздаю я каждый раз при перемещении полигона, потому что....а как иначе? Полигон изменил свое место положение на сцене, значит его вершина поменяла координаты, значит кругляха тоже должна поменять координаты отрисовки. Или я что-то упускаю? Или правильнее делать hide-show и setPos() у кругляхи?
Цитата Сообщение от Горбаг Посмотреть сообщение
Где ты работаешь с перемещением?
Пробовал работать с перемещением в самом итеме, получается ерунда. Сейчас переписал работу с перемещением в сцене, чтобы все обрабатывалось в ней.
Цитата Сообщение от Горбаг Посмотреть сообщение
И эти координаты передаешь сигналом родителю - итему.
Каким именно сигналом? Делать связь через слот-сигнал и писать connect или через evet прыгать по итемам?

Да и в обратную когда будет работа идти, т.е. от кругляхи, к полигону, я двигаю круглях, значит полигон надо целиком отрисовать заново. С новой вершиной. Я пока знаю как это сделать через пересоздание итема. Или надо запускать paint полигона и там перерисовывать?
0
184 / 176 / 57
Регистрация: 25.09.2014
Сообщений: 828
14.11.2016, 09:35 27
Если ты сейчас делаешь все на сцене, то какая вообще проблема? Клик(mousePressEvent) - определяешь, в кругляхе ли ты. Если в кругляхе, выставляешь флаг. Ведешь мышь (mouseMoveEvent) - проверяшь выставленный флаг. Если флаг в порядке - двигаешь круглях. Визуально так будет казаться. На самом же деле каждый раз, когда ты его двигаешь, ты перерисовываешь папашу - именно его. Ты ведь знаешь координаты углов и тот, который меняешь. В листе углов папаши одному из них меняешь координату, предварительно вызвав prepareGeometryChange(). По идее перерисовка папаши приведет к перерисовке дочерних итемов - кругляхов. Таким образом тебе самому не приходится за этим следить. Просто двигай родителя кругляха, если нажал на круглях.
Хотя все же и кругляхи придется двигать. Но черт с ними. Попробуй пока что перерисовать сам полигон именно в те точки, до которых ты двигаешь его за круглях...
0
161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
14.11.2016, 10:17  [ТС] 28
Цитата Сообщение от Горбаг Посмотреть сообщение
На самом же деле каждый раз, когда ты его двигаешь, ты перерисовываешь папашу - именно его
перерисовываю полигон, правильно? т.е. вызывать paint полигона? или пересоздать его? или что ты имел в виду, я не понял тебя.
Без какого то примера кода все тяжело воспринимается.
Цитата Сообщение от Горбаг Посмотреть сообщение
Попробуй пока что перерисовать сам полигон именно в те точки, до которых ты двигаешь его за круглях...
Я не могу сделать этого тк не понимаю как. Точнее сейчас я пытаюсь сделать так.
Работаю на сцене. Если был pressEvent на кругляхе, то выставляю соответствующий флаг, и когда event возвращается на сцену, то по новым координатам, пришедшим от кругляхи, я пересоздаю полигон, заменив одну из его вершин на новые координаты.
0
184 / 176 / 57
Регистрация: 25.09.2014
Сообщений: 828
14.11.2016, 10:33 29
Лучший ответ Сообщение было отмечено Sph как решение

Решение

Функция paint() вызывается каждый раз при перерисовке. В ней у тебя рисуются несколько линий по координатам углов, сохраненных в листе. Когда ты двигаешь со сцены круглях, ты у его родителя меняешь координату угла свой кастомной функцией - в нее передаешь индекс угла и его новое значение координаты. В самом полигоне в реализации этой функции ты СНАЧАЛА вызываешь prepareGeometryChange(), затем обновляешь координату в листе (по пришедшему индексу) на новое (пришедшее) значение. Все. Две строчки. Вроде должно сработать.
1
161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
14.11.2016, 10:59  [ТС] 30
Цитата Сообщение от Горбаг Посмотреть сообщение
В ней у тебя рисуются несколько линий по координатам углов, сохраненных в листе.
Создаю полигон так:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
QPolygonF mypolygon;
//......
PolyItem::PolyItem(QList<QPointF> point, QGraphicsScene *scene) 
{
//........
  for(int ii = 0; ii < point.size(); ii++)
    {
        mypolygon << point.at(ii);
    }
 
    setPolygon(mypolygon);
}
рисую так:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
void PolyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);
    QBrush brush(Qt::green);
    QPen pen(Qt::black,3);
 
        painter->setBrush(brush);
        painter->setPen(pen);
        painter->drawPolygon(mypolygon);
}
Создал метод setNewPoints в которой передаю новые координаты для смены позиции вершины, там же делаю prepareGeometryChange(); сделал по аналогии с документации. вызываю метод со сцены если двигаю круглях. Программа падает с Segmentation fault при попытке вызова prepareGeometryChange();
Где я ошибся?
0
184 / 176 / 57
Регистрация: 25.09.2014
Сообщений: 828
14.11.2016, 11:18 31
Первое, что на ум пришло, может и глупость, но полигон квадрата состоит из 4 линий, но 5 точек. Т.к. ему обязательно нужно первой и последней точкой указывать начало вроде бы. Если ты меняешь координату одной точки, ты уверен, что она не являлась при этом последней? А то по-моему полигон не сможет создаться, ведь он получится незамкнутым. Но это так, вопрос перестраховки. Сам не знаю, как он отреагирует, надо доку перечитать. С полигонами особо не работал - не создавал их руками.

Я бы еще поглядел на твою функцию setNewPoints
И на то, где и как она вызывается. А именно - указатель на круглях и полигон. Желательно всю фукнцию moveEvent'a
0
161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
14.11.2016, 14:13  [ТС] 32
UPD. разобрался. Пропустил строку и пытался обратиться к итему до того как его создал, отчего тот падал. Сейчас проверю передачу корректных вершин и посмотрю как будет себя итем вести.

Добавлено через 2 часа 54 минуты
WarpDrive, Горбаг
Спасибо за помощь!
Работаю из сцены. В moveEvent отлавливаю с кем я сейчас работаю, полигон или кругляха-вершина. И при работе с вершиной, вызываю
C++ (Qt)
1
poly_selected->setNewPoint(index,pos);
где poly_selected это выделенный в текущий момент полигон
setNewPoint это свой метод в который передаю с какой вершиной и ее координатами\новой позицией я сейчас работаю.
И соответственно в полигоне обновляю вершину
C++ (Qt)
1
2
3
4
5
void PolyItem::setNewPoint(int posPoint, QPointF newPoint)
{   
    prepareGeometryChange();
    mypolygon.replace(posPoint,newPoint);
}
А дальше надо только дописать реализацию на "запоминание" новых координат при releaseEvent и повторном pressEvent
По крайней мере сейчас все работает как надо!
0
14.11.2016, 14:13
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.11.2016, 14:13
Помогаю со студенческими работами здесь

Qml изменение размера Canvas при изменении размера окна
Может есть какой нибудь способ, чтобы при изменении размера окна (в моем случае window) изменялся...

Пропорциональное изменение размера tabControl1 при изменении размера формы
Всем hello. Посоветуйте, что сделать. На форме есть компоненты, делаю, чтобы при изменении...

Изменение размера обьектов при изменении размера графического окна
Можно ли в pascalABC.net сделать следующее: чтобы приизменении размера графического окна изменялись...

Изменение размера UserControl при изменении размера элемента на нем
Здравствуйте. У меня на UserControl находится TextBox. Выполняю построение. В конструкторе переношу...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru