默認只有QWidget才有setCursor接口,QCustomPlot也沒有為我們擴展它,所以我們自己增加可以設置鼠標形狀的接口

效果圖
void QCPLayerable::setCursor(const QCursor &cursor)
{
mHasCursor = true; // 新增的bool成員變量
mCursor = cursor; // 新增的QCursor成員變量
if (mParentPlot && mParentPlot->underMouse()) {
const auto layerableList = mParentPlot->layerableListAt(mParentPlot->mapFromGlobal(QCursor::pos()), false);
for (auto *layerable : layerableList) {
if (layerable->hasCursor()) {
QMetaObject::invokeMethod(mParentPlot, "setViewportCursor",
Q_ARG(QCursor, layerable->cursor()));
break;
}
}
}
}
void QCPLayerable::unsetCursor()
{
if (!mHasCursor || !mParentPlot)
return;
mHasCursor = false;
if (mParentPlot->underMouse() && mParentPlot->layerableAt(mParentPlot->mapFromGlobal(QCursor::pos()), false) == this) {
QMetaObject::invokeMethod(mParentPlot, "unsetViewportCursor");
}
}
同時為QCPLayerable新增鼠標進入和離開事件
virtual void hoverEnterEvent(QHoverEvent *event) { Q_UNUSED(event) }
virtual void hoverLeaveEvent(QHoverEvent *event) { Q_UNUSED(event) }
我們主要在QCustomPlot中的mouseMoveEvent事件中處理鼠標形狀的改變以及鼠標進入和離開QCPLayerable事件的傳遞
event->accept(); // 以上為源碼內容
auto list = layerableListAt(event->pos(), false);
QCPLayerable *hoveredLayerable = list.isEmpty() ? nullptr : list.first();
if (hoveredLayerable) {
if (mLastHoverLayerable != hoveredLayerable) {
if (mLastHoverLayerable) {
auto *item = static_cast<QCPAbstractItem *>(mLastHoverLayerable);
if (item) emit hoverLeaveItem(item);
QHoverEvent hoverEvent(QEvent::HoverLeave, QPointF(-1, -1), event->pos(), event->modifiers());
mLastHoverLayerable->hoverLeaveEvent(&hoverEvent);
}
mLastHoverLayerable = hoveredLayerable;
auto *item = static_cast<QCPAbstractItem *>(mLastHoverLayerable);
if (item) emit hoverEnterItem(item);
QHoverEvent hoverEvent(QEvent::HoverEnter, event->pos(), QPointF(-1, -1), event->modifiers());
mLastHoverLayerable->hoverEnterEvent(&hoverEvent);
}
}
// 以后可以優(yōu)化
foreach (auto *layerable, list) {
if (layerable->hasCursor()) {
setViewportCursor(layerable->cursor());
return;
}
}
if (mLastHoverLayerable) {
auto *item = static_cast<QCPAbstractItem *>(mLastHoverLayerable);
if (item) emit hoverLeaveItem(item);
QHoverEvent hoverEvent(QEvent::HoverLeave, QPointF(-1, -1), event->pos(), event->modifiers());
mLastHoverLayerable->hoverLeaveEvent(&hoverEvent);
mLastHoverLayerable = nullptr;
}
if (mHasStoredOriginalCursor) {
mHasStoredOriginalCursor = false;
setCursor(mOriginalCursor);
}
設置和恢復QCustomPlot的鼠標形狀,注意這兩個函數(shù)要聲明為Q_INVOKABLE
void QCustomPlot::setViewportCursor(const QCursor &newCursor)
{
if (!mHasStoredOriginalCursor) {
mHasStoredOriginalCursor = true;
mOriginalCursor = cursor();
}
setCursor(newCursor);
}
void QCustomPlot::unsetViewportCursor()
{
const auto layerableList = layerableListAt(mapFromGlobal(QCursor::pos()), false);
foreach (auto *layerable, layerableList) {
if (layerable->hasCursor()) {
setViewportCursor(layerable->cursor());
return;
}
}
if (mHasStoredOriginalCursor) {
mHasStoredOriginalCursor = false;
setCursor(mOriginalCursor);
}
}
我們可以通過設置setSelectionTolerance設置QCustomPlot的選擇誤差范圍來決定QCustomPlot的鼠標點擊(懸?。┬袨?/p>
注意要將QCPLayerable設置為QCustomPlot的友元類