#c #qt #plot #qpainterpath
#c #qt #график #qpainterpath
Вопрос:
Я новичок в C
, Qt
и Visual Studio
, и это мой первый пост о переполнении стека.
Заранее прошу прощения, если это повторяющийся вопрос, я пытался найти аналогичный вопрос, но не смог его найти. Дайте мне знать, если это повторный вопрос, и я удалю его.
Я пытаюсь создать линейный график с помощью QWidget::paintEvent()
. Линейный график, который я рисую, на самом деле является QPainterPath
. Я хочу определить, когда мышь наводится на мой линейный график, и поэтому я создаю небольшой прямоугольник, где находится мой курсор мыши, и определяю, когда этот прямоугольник пересекается с моим линейным графиком, используя bool QPainterPath::intersects()
функцию. Проблема в том, что эта функция возвращает true, даже если моя мышь находится не совсем над моим линейным графиком. На изображении 1 (мне пока не разрешено вставлять изображения) мой линейный график представляет собой толстую черную кривую, и bool QPainterPath::intersects()
возвращает значение true, даже когда мой курсор находится над желтой областью. Согласно документу Qt это потому, что:
Существует пересечение, если какая-либо из линий, составляющих прямоугольник, пересекает часть пути или если какая-либо часть прямоугольника перекрывается с любой областью, ограниченной путем.
Невозможно иметь QPainterPath
без какой-либо замкнутой области, поскольку Qt предоставляет только два типа заливки для QPainterPath
: Qt::OddEvenFill
или Qt::WindingFill
. (Честно говоря, я нахожу это своего рода раздражающим, поскольку открытый путь представляет собой серию отрезков, соединенных сквозным образом, если кто-то хочет охватить область, они могут легко соединить первую и последнюю точки, используя функции QPainterPath::lineTo()
или QPainterPath::moveTo()
)
В любом случае, я решил стать умнее Qt
и нарисовал два дополнительных, QPainterPath
где pathUp
они находятся на несколько пикселей выше моего линейного графика и pathDn
на несколько пикселей ниже моего линейного графика. На изображении 2 показаны эти 3 линейных графика: красный — pathUp
, черный — реальный линейный график, а зеленый — pathDn
. Я думал, что смогу обнаружить пересечение в QWidget::mouseMoveEvent()
, используя следующий код:
// cRect: Rectangle at mouse cursor position
if((pathUp.intersects(cRect) amp;amp; (!pathDn.intersects(cRect))) || ((!pathUp.intersects(cRect)) amp;amp; pathDn.intersects(cRect)))
{
qDebug() << "Intersects";
}
Но это по-прежнему приводит к неправильным результатам, потому что теперь закрытая область отличается, как вы можете видеть на изображении 3, зеленая область — это закрытая область pathDn
, а красная область — это закрытая область pathUp
. Толстая черная кривая — это снова линейный график, на котором я хочу обнаружить наведение курсора мыши. На эту закрытую область не влияет Qt::setFillRule
of QPainterPath
.
Что еще более расстраивает, так это то, что я попробовал этот метод, используя QPolygonF
вместо QPainterPath
on QWidget
, и результаты были точно такими же. Я также пробовал QGraphicsView
, там я использовал QGraphicsPathItem
для создания своего линейного графика, а затем использовал QGraphicsScene::focusItemChanged()
signal для определения того, когда я нажимаю на свой линейный график. Это снова привело к тому же результату обнаружения щелчка, когда мой курсор находится над закрытой областью. Я не хочу создавать пользовательский QGraphicsItem
(если мне это абсолютно не нужно) просто для переопределения его hoverEnterEvent()
и hoverLeaveEvent()
метода из-за ограничений, налагаемых на boundingRect()
из QGraphicsItem
, как описано в документах Qt:
QGraphicsScene ожидает, что все элементы boundingRect() и shape() останутся неизменными, если не будет получено уведомление. Если вы хотите каким-либо образом изменить геометрию элемента, вы должны сначала вызвать prepareGeometryChange(), чтобы разрешить QGraphicsScene обновлять свою бухгалтерию.
Поскольку я создаю график в режиме реального времени, boundingRect()
будет меняться довольно часто (> 20 Гц), что приведет к дополнительной вычислительной нагрузке на программное обеспечение. Есть ли какой-либо способ решить мою проблему без создания пользовательского QGraphicsItem
?
PS Я использую Stack Overflow в течение многих лет всякий раз, когда я застревал. Я просто никогда не создавал здесь учетную запись, потому что мне никогда не нужно было ничего публиковать. Вы, ребята, лучшие, и я очень рад быть частью этого сообщества!
Комментарии:
1. К вашему сведению, Qt уже предоставляет готовое решение Qt Charts .
2. Привет! да, я пробовал
Qt Charts
, но это довольно сложно, и я не могу добавить к нему дополнительные функции, которые мне нужны на моем графике. Другими словами, это довольно ограничительно. Кроме того, это медленно, и я хочу построить графикQVector<doubles>
длиной 100 000 за несколько 10 секунд миллисекунд.