首页 > 解决方案 > Qt Bug:QGraphicsWidget 不将负坐标视为客户区

问题描述

我正在用 QGraphicsWidget 绘制正方形,中心应该是坐标 (0, 0)。为了实现这一点,我覆盖了 boundingRect()

QRectF boundingRect() const override
{
    QRectF Boundary(-SIZE / 2, -SIZE / 2, SIZE, SIZE);
    return Boundary;
}

我还在setCursor(Qt::CrossCursor)Constructor 中进行了设置,这样我就可以将鼠标悬停在 Widget 上并查看实际客户区的开始和结束位置。

我希望小部件从(-SIZE/2, -SIZE/2)到位于广场的中心(SIZE/2, SIZE/2)(0, 0)事实上,它实际上是正确显示的。但并非所有客户区都可用于拖动。 当在正坐标中单击时,只能拖动小部件: (0, 0)(SIZE/2, SIZE/2)。看看截图和paint()功能。

绿色区域是从 (-SIZE/2, -SIZE/2) 到 (SIZE/2, SIZE/2) 的完整客户区。 读取区域从 (0, 0) 到 (SIZE/2, SIZE/2)

void paint(QPainter* Painter, const QStyleOptionGraphicsItem* Option, QWidget* Widget) override
{
    // Draw the item. The origin should be at (0, 0).
    Painter->setPen(Qt::green);
    Painter->drawRect(-SIZE / 2, -SIZE / 2, SIZE, SIZE);
    Painter->drawText(boundingRect(), Qt::AlignCenter | Qt::AlignVCenter, "center");

    // This is the area, which can be used to drag the item.
    // [only when boundaryRect() sets origin to (-SIZE/2, -SIZE/2)]
    Painter->setPen(Qt::red);
    Painter->drawRect(0, 0, SIZE / 2, SIZE / 2);
}

鼠标在红场:光标更改为十字 --> 区域被视为客户区域。项目可以拖动。

在此处输入图像描述

鼠标在绿色方块中:光标未更改为十字 --> 区域不被视为客户区域。无法拖动项目。

我已经花了很多时间研究并尝试自己解决这个问题。我无法弄清楚,我现在相信这是一个错误 - 我是对的吗?

我正在使用 Qt 版本5.15.2+kde+r961-1

现在这是完整的最小工作示例

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsWidget>
#include <QMainWindow>
#include <QPainter>

class BlockWidget : public QGraphicsWidget
{
    constexpr static double SIZE = 100;

public:
    BlockWidget()
    {
        setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
        setCursor(Qt::CrossCursor);
        setGeometry(boundingRect());
    }

void paint(QPainter* Painter, const QStyleOptionGraphicsItem* Option, QWidget* Widget) override
{
    // Draw the item. The origin should be at (0, 0).
    Painter->setPen(Qt::green);
    Painter->drawRect(-SIZE / 2, -SIZE / 2, SIZE, SIZE);
    Painter->drawText(boundingRect(), Qt::AlignCenter | Qt::AlignVCenter, "center");

    // This is the area, which can be used to drag the item.
    // [only when boundaryRect() sets origin to (-SIZE/2, -SIZE/2)]
    Painter->setPen(Qt::red);
    Painter->drawRect(0, 0, SIZE / 2, SIZE / 2);
}

    QRectF boundingRect() const override
    {
        QRectF Boundary(-SIZE / 2, -SIZE / 2, SIZE, SIZE);
        return Boundary;
    }
};

int main(int argc, char** argv)
{
    QApplication App(argc, argv);
    QMainWindow Frame;
    Frame.setWindowTitle("Graphics Widget Frame");

    QGraphicsScene Scene;
    Scene.addItem(new BlockWidget);

    QGraphicsView* View = new QGraphicsView(&Scene);
    Frame.setCentralWidget(View);

    Frame.show();

    return App.exec();
}

标签: c++qtqt5qgraphicswidget

解决方案


推荐阅读