Russian Qt Forum
Апрель 25, 2024, 00:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Перемещение и привязка прямоугольника на форме (QWidget)  (Прочитано 5913 раз)
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« : Июнь 26, 2015, 09:39 »

На окошке рисуется прямоугольник, который можно перемещать мышкой.
Перемещение может быть: свободным и с привязкой к сетке

Вот с привязкой к сетке у меня фигня выходит -- прямоугольник прикрепляется, но после начала движения прямоугольник тянется не за ту точку, в которую мы тыкнули на нем, а примерно верхний левый угол. Это особенно заметно, когда за нижний правый угол его хватает, перемещаешь, и он притягивается к курсору в верхнему правому углу, а после привязывается к ближайшей стороне ячейки сетки

Как сделать, чтобы работало хорошо? Улыбающийся

При свободном перемещении такого нету

Алгоритм перемещения прямоугольника по форме:
Код
C++ (Qt)
   void mouseMoveEvent(QMouseEvent * e) {
       if (press) {
           QPointF delta = e->posF() - lastPos;
           rect.moveTo(rect.topLeft() + delta);
 
           // Если включена привязка
           if (snap.isChecked()) {
               QPointF pos = e->posF();
               double x = pos.x();
               double y = pos.y();
               x -= int(x) % cellSize.width();
               y -= int(y) % cellSize.height();
 
               pos = QPointF(x, y);
               rect.moveTo(pos);
               pos -= QPointF(x, y) - rect.topLeft();
               rect.moveTo(pos);
           }
       }
 
       lastPos = e->posF();
       update();
   }
 

Минимально-компилябельный пример приложен
Записан

Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Июнь 26, 2015, 09:55 »

Не проверял, но по-моему правильно иак
Код
C++ (Qt)
if (snap.isChecked()) {
 int w = cellSize.width();
 int h = cellSize.height();
 rect.moveTo(rect.left() / w * w, rect.top() / h * h);
}
И вообще, давно пора решать задачи посложнее  Улыбающийся
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #2 : Июнь 26, 2015, 09:57 »

Не проверял, но по-моему правильно иак
Код
C++ (Qt)
if (snap.isChecked()) {
 int w = cellSize.width();
 int h = cellSize.height();
 rect.moveTo(rect.left() / w * w, rect.top() / h * h);
}
И вообще, давно пора решать задачи посложнее  Улыбающийся

не работает Улыбающийся
Записан

__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #3 : Июнь 26, 2015, 10:15 »

К сожалению, нет времени на попытки поиграть с этой задачей.
Имхо, lastPos нужно сохранять при клике. При смене позиции рамки перезаписывать lastPos. Только это заметил.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #4 : Июнь 26, 2015, 10:21 »

К сожалению, нет времени на попытки поиграть с этой задачей.
Имхо, lastPos нужно сохранять при клике. При смене позиции рамки перезаписывать lastPos. Только это заметил.

Точно! Вы правы Улыбающийся
Записан

Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Июнь 26, 2015, 12:47 »

Народная примета: исходная точка (с которой начался драг) должна храниться неизменной, иначе драг "уползет". Ладно, "побалуемся плюшками"  Улыбающийся (аттач) Пришлось заменить posF на localPos (версия новее)



Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #6 : Июнь 26, 2015, 12:59 »

Народная примета: исходная точка (с которой начался драг) должна храниться неизменной, иначе драг "уползет". Ладно, "побалуемся плюшками"  Улыбающийся (аттач) Пришлось заменить posF на localPos (версия новее)





О, спасибо! Заработало Улыбающийся
Записан

__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #7 : Июнь 26, 2015, 13:34 »

Кстати, я не понял, зачем использовать float... Координаты экрана, ведь, в int. И там, где вы x и y высчитываете, они тоже должны быть int, имхо.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #8 : Июнь 26, 2015, 13:39 »

Кстати, я не понял, зачем использовать float... Координаты экрана, ведь, в int. И там, где вы x и y высчитываете, они тоже должны быть int, имхо.

По условию задачи  Улыбающийся
Записан

Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Июнь 26, 2015, 13:45 »

. Координаты экрана, ведь, в int
Уже нет, во всяком случае - не везде. (Получил за это когда переходил на какаву)
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #10 : Июнь 26, 2015, 14:08 »

Опа. А где они во float?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Июнь 26, 2015, 14:32 »

Опа. А где они во float?
Ну хотя бы в QMouseEvent. Напр предположение что QCursor::pos() возвращает то же самое значение что и в QMouseEvent (до тех пока мышь не передвинулась) оказалось неверным т.к. Mac OSX выдает флоты которые округляются по-разному.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.108 секунд. Запросов: 22.