【问题标题】:Weird behaviour when dragging QGraphicsItem拖动 QGraphicsItem 时的奇怪行为
【发布时间】:2018-06-05 16:08:50
【问题描述】:

我正在尝试在 Qt 中创建一个箭头项,所以我以这个示例为基础:http://doc.qt.io/qt-5/qtwidgets-graphicsview-diagramscene-arrow-cpp.html

唯一的区别是我想将箭头连接到一个项目而不是两个项目。 一切正常,除了当我尝试拖动我的项目时,它会留下一条模糊的痕迹,好像它正在绘制整个拖动动作,如果我 alt tab 它消失了。

这是在我拖动之前:

接下来是:

只有箭头的行为是这样的,我认为它的绘制事件可能有问题:

void myArrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

qreal arrowSize = 20;
double angle = std::atan2(-line().dy(), line().dx());

QPointF arrowP1 = line().p1() + QPointF(sin(angle + M_PI / 3) * arrowSize,
                                cos(angle + M_PI / 3) * arrowSize);
QPointF arrowP2 = line().p1() + QPointF(sin(angle + M_PI - M_PI / 3) * arrowSize,
                                cos(angle + M_PI - M_PI / 3) * arrowSize);

arrowHead.clear();
arrowHead << line().p1() << arrowP1 << arrowP2;

painter->drawLine(line());
painter->drawPolygon(arrowHead);
}

如果我通过删除这条线 painter-&gt;drawPolygon(arrowHead) 来取出箭头,那么这条线本身就可以正常工作。

这里是整个源项目:https://github.com/Matheusih/0000000123

有什么提示吗?

【问题讨论】:

    标签: qt draggable qgraphicsitem


    【解决方案1】:

    问题是MyArrowboundingRect 仅以QLineF 为基础而不是箭头,这会产生不希望的效果。

    我的解决方案建议使用QGraphicsPathItem 而不是QGraphicsLineItem,除了我不明白你在moveLineToCenter 中实现的逻辑,我认为它是不必要的,我已对其进行了修改以更新其位置:

    myarrow.h

    #ifndef MYARROW_H
    #define MYARROW_H
    
    class CustomRect;
    
    #include <QGraphicsPathItem>
    
    class MyArrow : public QGraphicsPathItem
    {
    public:
        MyArrow(CustomRect *rect);
        void updatePosition(QPointF p1, QPointF p2);
    private:
        CustomRect *myrect;
    };
    
    #endif // MYARROW_H
    

    myarrow.cpp

    #include "customrect.h"
    #include "myarrow.h"
    
    #include <QPainter>
    
    #include <cmath>
    
    MyArrow::MyArrow(CustomRect *rect){
        myrect = rect;
        QPointF p = rect->boundingRect().center();
        updatePosition(p - QPointF(0, 50), p - QPointF(0, 250));
        setFlag(QGraphicsLineItem::ItemIsSelectable);
    }
    
    void MyArrow::updatePosition(QPointF p1, QPointF p2)
    {
    
        const qreal arrowSize = 20;
    
        QPainterPath path;
    
        path.moveTo(p1);
        path.lineTo(p2);
    
        QPointF diff = p2-p1;
        double angle = std::atan2(-diff.y(), diff.x());
    
        QPointF arrowP1 = p1 + QPointF(sin(angle + M_PI / 3) * arrowSize,
                                        cos(angle + M_PI / 3) * arrowSize);
        QPointF arrowP2 = p1 + QPointF(sin(angle + M_PI - M_PI / 3) * arrowSize,
                                        cos(angle + M_PI - M_PI / 3) * arrowSize);
        QPolygonF arrowHead;
        arrowHead << p1 << arrowP1 << arrowP2 << p1;
        path.moveTo(p1);
        path.addPolygon(arrowHead);
    
        setPath(path);
    }
    

    customrect.h

    #ifndef CUSTOMRECT_H
    #define CUSTOMRECT_H
    
    #include <QGraphicsPixmapItem>
    
    class MyArrow;
    
    class CustomRect : public QGraphicsRectItem
    {
    public:
        CustomRect (const QRectF& rect);
        void addLine(MyArrow *line);
        QVariant itemChange(GraphicsItemChange change, const QVariant &value);
    
        void moveLineToCenter(QPointF newPos);
    
    private:
        QList<MyArrow *> arrows;
    };
    #endif // CUSTOMRECT_H
    

    customrect.cpp

    #include "customrect.h"
    #include "myarrow.h"
    
    CustomRect::CustomRect(const QRectF &rect) : QGraphicsRectItem(rect){
        setFlag(QGraphicsItem::ItemIsMovable);
        setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
    }
    
    void CustomRect::addLine(MyArrow *line) {
        arrows << line;
    }
    
    QVariant CustomRect::itemChange(GraphicsItemChange change, const QVariant &value)
    {
        if (change == ItemPositionChange && scene()) {
            QPointF newPos = value.toPointF();
            moveLineToCenter(newPos);
        }
        return QGraphicsItem::itemChange(change, value);
    }
    
    void CustomRect::moveLineToCenter(QPointF newPos) {
    
        for(MyArrow *arrow: arrows) {
            arrow->setPos(newPos);
        }
    }
    

    完整的解决方案可以在下面link

    【讨论】:

    • 太完美了,感谢您的帮助。您能否更详细地解释导致我的问题的原因以及使用 QGraphicsPathItem 如何解决它?我会很感激,因为我还在学习 Qt。
    猜你喜欢
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    • 2019-08-25
    • 1970-01-01
    • 2019-11-15
    相关资源
    最近更新 更多