Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Crazy Sage от Ноябрь 19, 2014, 08:13



Название: MouseClickEvent по сложной маске
Отправлено: Crazy Sage от Ноябрь 19, 2014, 08:13
Добрый день, нужна помощь с обработкой мышиных событий:
Есть дизайн программы, с шестиугольными примыкающими друг к другу кнопками и прочей радостью, которую не очень хочется реализовывать отдельными виджетами. Отслеживать mouseClickEvent по координатам тоже не очень удобно, но уже вариант. Вопрос - можно ли как-то сделать набор масок по которым определять область mouseClick'а? Можно конечно вручную подключать по битмапу на каждую кнопку виджета и брать в цикле цвет с каждой из них или сделать разноцветную картинку и проверять цвет  по координате клика, но может есть какие-то менее порнографичные способы?


Название: Re: MouseClickEvent по сложной маске
Отправлено: Bepec от Ноябрь 19, 2014, 09:06
На мой взгляд отслеживать по координатам самое простое. Тупо пишете ф-цию принимающую координаты и выдающую номер/идентификатор кнопки. А картинку уже сами рисуете под формулу :) Хоть гексаэдры туда вписывайте.


Название: Re: MouseClickEvent по сложной маске
Отправлено: vulko от Ноябрь 19, 2014, 09:14
кнопка рисуется как картинка или по координатам?

если как картинка, то у неё прозрачный фон. делаешь отдельным виджетом, при клике смотришь локальную позицию мышки (внутри виджета) и проверяешь пиксель по этим координатам на прозрачность.

но это ничем не лучше и не быстрее чем проверка по координатам.


Название: Re: MouseClickEvent по сложной маске
Отправлено: Igors от Ноябрь 19, 2014, 10:19
Есть дизайн программы, с шестиугольными примыкающими друг к другу кнопками и прочей радостью,
Какой прочей? Определить что точка внутри шестиугольника - детская забава, что там еще? Может просто без масок посчитать да и все?


Название: Re: MouseClickEvent по сложной маске
Отправлено: Crazy Sage от Ноябрь 19, 2014, 10:26
Понял, буду вспоминать курс компьютерной геометрии и графики.
Потому что не нужно было ни разу, вот и не помню нифига.


Название: Re: MouseClickEvent по сложной маске
Отправлено: Old от Ноябрь 19, 2014, 10:31
Понял, буду вспоминать курс компьютерной геометрии и графики.
Потому что не нужно было ни разу, вот и не помню нифига.
Вспомнить всегда хорошо, а потом можно посмотреть на QRegion + QPolygon и использовать:
bool QRegion::contains(const QPoint & p) const


Название: Re: MouseClickEvent по сложной маске
Отправлено: Fregloin от Ноябрь 19, 2014, 11:05
может есть смысл задействовать графическую сцену, тогда она уже сама будет вам возвращать какая кнопка (элемент) нажата?
посмотрите QGraphicsView/QGraphicsScene/QGraphicsItem


Название: Re: MouseClickEvent по сложной маске
Отправлено: Crazy Sage от Ноябрь 19, 2014, 11:07
Со сценами я умею работать, просто дизайн в виде одной картинки, на которой все кнопки разрисованы, при этом очень сжатые сроки, поэтому хочется минимизировать работу и не резать эту картинку на элементы, что для сцены всё равно потребуется.


Название: Re: MouseClickEvent по сложной маске
Отправлено: Igors от Ноябрь 19, 2014, 11:33
Ну если надо срочно..

Код
C++ (Qt)
bool PointInsideNGon( const QPointF & src,  // point to test
                               const QRectF & R,     // N-gon bounding rectangle
                               int N,             // N-gpn side count
                               qreal phase = 0 )      // 0 = corner on x-axis
{
// point in local space
QPointF pt = src - R.center();
pt.rx() /= R.width() / 2;
pt.ry() /= R.height() / 2;
 
// angle inside sector
qreal angle = atan2(-pt.y(), pt.x()) + phase;
qreal step = M_PI * 2 / N;
int num = (int) (angle / step);
angle = (step + 0.5) * num;
 
// check dot
return pt.x() * cos(angle) + pt.y() * sin(angle) <= cos(step / 2);
}
Писал здесь, возможны ошибки. Смысл такой: точка попадает в один из секторов N-угольника (num), и проекция на биссектрису этого сектора должна быть меньше косинуса половины угла сектора. Нарисуйте на бумажке, все сразу станет ясно


Название: Re: MouseClickEvent по сложной маске
Отправлено: Crazy Sage от Ноябрь 19, 2014, 11:43
Спасибо