I. Требуются инструмент, рисующий прямоугольники. Также требуются выделяющие инструменты (овал, прямоугольник). Принцип действия одинаков — юзер тыкает кнопкой мыши по View, растягивает нечто, видит как оно изменяется, отпускает кнопку и мы получаем в своё распоряжение заданный QRectF (как я понимаю, с овалами также лучше работать через QRectF).
То есть работать с этим делом предполагается как-то так (по аналогии с QRubberBand):
void Widget::mousePressEvent(QMouseEvent *event)
{
origin = event->pos();
if (!myInstrument)
myInstrument = new MyInstrument(MyInstrument::НУЖНАЯ_ФОРМА, this);
myInstrument->setGeometry(QRect(origin, QSize()));
myInstrument->show();
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
myInstrument->setGeometry(QRect(origin, event->pos()).normalized());
}
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
myInstrument->hide();
// делаем, что надо и удаляем myInstrument
}
Если я верно понимаю, в Qt из подобного есть только прямоугольное выделение — QRubberBand. Но оно умеет рисовать только прямоугольники и отрезки. То есть надо бы унаследовать и добавить нужные формы, но сколько я ни медитировал на код этого виджета, я так и не понял, где там вообще рисуется прямоугольник. Что нужно сделать, чтобы оно рисовало овалы (и вообще возможно ли это)?
II. Ещё требуется выделение-лассо (точнее, полигональное выделение) — юзер расставляет точки, соединяет начальную точку с конечной и мы получаем в своё распоряжение полигон (как в гимпе, только без возможности рисования кривых). Как быть, от чего идти? От QGraphicsItem?
III. На сцене расположены прямоугольнички. Требуется функция, которая возвращала бы ссылки на все прямоугольники, которые более чем половиной площади попадают в заданную фигуру (в моём случае в элипс или полигон). Это нужно для выделения. Представляю себе так:
void MyGraphicsScene::setSelectionArea ( const QPainterPath & path, const QTransform & deviceTransform )
{
// Находим все фигуры, которые перекаются c selectionArea() методом IntersectsItemShape и методом ContainsItemShape. Вычитаем второе из первого, для полученного списка обычной математикой находим площадь пересечения, дальше всё ясно
}
Далее работа идёт через стандартный QList<QGraphicsItem *> MyGraphicsScene::selectedItems () const.
Есть ли более изящное решение? В частности, хотелось бы как-то определять площадь пересечения средствами Qt, а не своими алгоритмами (которые надо делать отдельно для элипсов и полигонов).