拖动QGraphicsItem

时间:2018-06-05 16:08:50

标签: qt draggable qgraphicsitem

我试图在Qt中创建一个箭头项目,所以我基于这个例子:http://doc.qt.io/qt-5/qtwidgets-graphicsview-diagramscene-arrow-cpp.html

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

在我拖动之前: enter image description here

以下是: enter image description here

只有箭头表现得像那样,我相信它的油漆事件可能有问题:

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->drawPolygon(arrowHead)取出箭头,则该行本身可以正常工作。

以下是整个源项目:https://github.com/Matheusih/0000000123

请提供任何提示?

1 个答案:

答案 0 :(得分:0)

问题在于MyArrow QLineF仅以QGraphicsPathItem为基础,而不是箭头,这会产生不良影响。

我的解决方案建议使用QGraphicsLineItem而不是moveLineToCenter,除了我不理解你在#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.h

#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);
}

<强> myarrow.cpp

#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.h

#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);
    }
}

<强> customrect.cpp

from rasa_core.channels import HttpInputChannel
from rasa_core.agent import Agent
from rasa_core.interpreter import RasaNLUInterpreter
#from rasa_slack_connector import SlackInput

nlu_interpreter = RasaNLUInterpreter('./models/nlu/default/moodnlu')
agent = Agent.load('./models/dialogue',interpreter = nlu_interpreter)


# With Slack
# https://api.slack.com/apps/AASPDV196/oauth?
#input_channel = SlackInput('OAuth Access Token','Bot User OAuth Access Token', 'Verification Token',True)

#agent.handle_channel(HttpInputChannel(5004,'/',input_channel))

# With inner app
input_channel = SlackInput('OAuth Access Token','Bot User OAuth Access Token', 'Verification Token',True)
agent.handle_channel(HttpInputChannel(5000,'/',input_channel))

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

中找到