Я создаю редактор с использованием C ++ / Qt, в котором есть ощущение щелчка и перетаскивания. Поведение аналогично редакторам схем (Eagle, KiCAD и т. Д.), Microsoft Visio или другим программам, в которых объекты перетаскиваются с панели инструментов в центральную область редактирования.
Моя проблема в том, что когда пользователь щелкает внутри пользовательского виджета, я хочу иметь возможность выбрать экземпляр похожего на блок объекта и манипулировать им. Там также будут линии, соединяющие коробки вместе. Однако я не могу выбрать эффективный метод для выбора этих объектов.
У меня есть две основные мысли о том, как сделать программирование для этого: во-первых, виджет, который рисует весь редактор, просто инкапсулирует каждый экземпляр блока. Другой заключается в том, чтобы каждый экземпляр блока (который находится в моей модели) имел при себе экземпляр QWidget, который обрабатывал бы рендеринг блока (который был бы в моем представлении … но в итоге он был бы прочно привязан к модель). Что касается линий, соединяющих их, так как они не имеют прямоугольных ограничительных рамок, они должны будут отображаться с помощью содержащего виджета.
Итак, вот краткое изложение того, как я это вижу:
Итак, теперь, когда есть немного фона, для 2-го метода я планирую иметь каждый прямоугольный экземпляр, имеющий ограничивающий прямоугольник и линии, представленные ограничивающими прямоугольными сегментами шириной 3-4 пикселя (они находятся под углами 90 градусов) , Я мог бы пройтись по каждой клетке и строке, но это кажется неэффективным.
Большой вопрос: есть ли какая-то структура данных, в которой я могу держать прямоугольники и связывать их с виджетами (или чем-то еще в этом отношении), а затем назначать им две координаты (например, координаты мыши) и заставлять их выплевывать меня из ограничивающего прямоугольника? или связанный объект, внутри которого находятся эти координаты?
Похоже, ваш реальный вопрос в том, чтобы найти хороший способ реализации вашего редактора, а не в особенностях производительности пересечения прямоугольников.
Вы можете быть заинтересованы в Qt’s «Diagram Scene» пример проекта, который демонстрирует QGraphicsScene
API. Это звучит как хорошая сценарий, который вы описываете. (Полный источник для примера поставляется с Qt.)
Самое приятное то, что вам все еще не нужно самостоятельно выполнять тестирование на попадание, потому что API уже предоставляет то, что вы ищете (например, QGraphicsScene::itemAt()
).
Стоит отметить, что внутренне, QGraphicsScene
использует простой итеративный метод для выполнения тестов на попадание. Как уже отмечали другие, это не будет серьезным узким местом, если ваши сцены не имеют много отдельных предметов.
Других решений пока нет …