Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我的QGraphicsItem项目不会被鼠标注意到_C++_Qt_Graphics_Mouseevent - Fatal编程技术网

C++ 我的QGraphicsItem项目不会被鼠标注意到

C++ 我的QGraphicsItem项目不会被鼠标注意到,c++,qt,graphics,mouseevent,C++,Qt,Graphics,Mouseevent,我正在尝试移动我的物品。。。唯一可行的方法是遍历所有项目并检查鼠标位置: class Item : public QGraphicsItem { Item() { setFlag(ItemIsMovable); setFlag(ItemIsSelectable); scale = 10; } QRectF boundingRect() const; void paint(QPainter *painter); // had to implement this beca

我正在尝试移动我的物品。。。唯一可行的方法是遍历所有项目并检查鼠标位置:

class Item : public QGraphicsItem
{
    Item() { setFlag(ItemIsMovable); setFlag(ItemIsSelectable); scale = 10; }
    QRectF boundingRect() const;
    void paint(QPainter *painter);   // had to implement this because I don't know how to get the QStyleOptionGraphicsItem to call the paint below
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
               QWidget *widget) {paint(painter);}   // never called
    void update() {}
    int scale, x, y;
};

// scale is Item property set by caller, x and y also set by caller based on viewport position of item center
QRectF Item::boundingRect() const
{
    return QRectF(x - 30 - scale, y - 30 - scale,
                  30 + 3 * scale, 20 + 3 * scale);
}

void Item::paint(QPainter *painter)
{
    update();
    painter->drawRect(boundingRect());
}

class CollectionView : public QGraphicsView
{
    Q_OBJECT    
public:
    CollectionView(QWidget *parent = 0);    
    QList<Item*> *m_items;
protected:
    virtual void paintEvent(QPaintEvent * event);
    virtual void mousePressEvent(QMouseEvent * event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
};

CollectionView::CollectionView(QWidget *parent)
    : QGraphicsView(parent)
{
    QGraphicsScene *s = new QGraphicsScene(this);
    setScene(s);
    setViewportUpdateMode(BoundingRectViewportUpdate);
    m_items = new QList<Item*>();
}

void CollectionView::paintEvent(QPaintEvent * /* event */)
{
    QPainter painter(this->viewport());

    for(int i = 0; i< m_items->size(); i++)
    {
        Item* item = m_items->at(i);
        //scene()->addItem(item);   // this crashes
        item->paint(&painter);
    }
}

void CollectionView::mousePressEvent(QMouseEvent* event)
{
    // if I add this and comment the rest, items don't move
    //QGraphicsView::mousePressEvent(event);

    foreach (QGraphicsItem *item, this->items(event->pos()))
    { /* never gets inside */ }
    foreach (QGraphicsItem *item, this->items(event->globalPos()))
    { /* never gets inside */ }

    // the following works though:
    for (int i = 0; i < m_items->size(); i++)
    {
        Item* currentItem = m_items->at(i);
        if(!currentItem->boundingRect().contains(event->pos()))
            continue;
        if (event->button() == Qt::LeftButton)
            { /* I can get the item index and its relative position to mouse
                 then pass this info to the mouseReleaseEvent, and it works */ }
        break;
    }
}
类项目:公共QGraphicsItem
{
Item(){setFlag(ItemIsMovable);setFlag(itemisselect);scale=10;}
QRectF boundingRect()常量;
void paint(QPainter*painter);//必须实现此功能,因为我不知道如何让QStyleOptionGraphicsItem调用下面的绘画
无效油漆(QPainter*油漆工、const QstyleOption Graphic Sitem*选项、,
QWidget*widget){paint(painter);}//从未调用
无效更新(){}
整数刻度,x,y;
};
//比例是由调用者设置的项目属性,x和y也是由调用者根据项目中心的视口位置设置的
QRectF项::boundingRect()常量
{
返回QRectF(x-30标度,y-30标度,
30+3*刻度,20+3*刻度);
}
无效项::油漆(油漆工*油漆工)
{
更新();
painter->drawRect(boundingRect());
}
类集合视图:公共QGraphicsView
{
Q_对象
公众:
CollectionView(QWidget*parent=0);
QList*m_项目;
受保护的:
虚拟虚空paintEvent(QPaintEvent*事件);
虚拟无效MousePresseEvent(QMouseEvent*事件);
虚拟无效mouseReleaseEvent(QMouseEvent*事件);
};
CollectionView::CollectionView(QWidget*父项)
:QGraphicsView(父级)
{
Qgraphicscene*s=新的Qgraphicscene(本);
(s);
setViewportUpdateMode(BoundingRectViewportUpdate);
m_items=new QList();
}
void CollectionView::paintEvent(QPaintEvent*/*event*/)
{
QPainter painter(此->视口());
对于(int i=0;isize();i++)
{
项目*项目=m_项目->在(i)处;
//scene()->addItem(item);//这会崩溃
项目->油漆和油漆工;
}
}
void CollectionView::MousePresseEvent(QMouseEvent*事件)
{
//如果我添加此内容并对其余内容进行注释,则项目不会移动
//QGraphicsView::MousePresseEvent(事件);
foreach(QGraphicsItem*item,this->items(event->pos()))
{/*永远不会进入*/}
foreach(QGraphicsItem*item,this->items(event->globalPos()))
{/*永远不会进入*/}
//但以下工作仍然有效:
对于(int i=0;isize();i++)
{
Item*currentItem=m_items->at(i);
如果(!currentItem->boundingRect()包含(事件->位置())
继续;
如果(事件->按钮()==Qt::LeftButton)
{/*我可以获取项目索引及其与鼠标的相对位置
然后将此信息传递给mouseReleaseEvent,它就会工作*/}
打破
}
}
如果我可以使用QGraphicsView/qgraphicscene/QGraphicsItem方法来移动项目或获取上下文菜单,那将是最好的。。。我还不知道怎么做

但是,如果我必须实现鼠标操作,最好是遍历在鼠标位置找到的项目,而不是列表中的所有项目(可能更大)

为什么我的尝试不起作用?(或者,如何让QGraphicscene/QGraphicsView完成所有工作并移动项目,而无需编写任何代码?这就是项目的目的是可修改的..对吗?)

更新:添加了
paintEvent
的代码。。。不幸的是,我没能打电话给警察

无效油漆(QPainter*油漆工、const QstyleOption Graphic Sitem*选项、, QWidget*widget)


油漆的版本-它可能会被类似
scene()->addItem(项目)的东西使用-但该特定调用会导致程序崩溃。。。上面的绘制方法从未被调用,但我知道这是他
QGraphicsItem
的官方绘制方法。。。这么简单的代码却又这么混乱。

首先,尝试使用一个简单的项目和一个基本的Graphicscene和View。就像这样:

    class GraphicsItem : public QGraphicsItem
{
public:
    GraphicsItem(QWidget* parent) {
        setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
    }
    QRectF boundingRect() const
       {
           qreal penWidth = 1;
           return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
                         20 + penWidth, 20 + penWidth);
       }

       void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                  QWidget *widget)
       {
           painter->drawRoundedRect(-10, -10, 20, 20, 5, 5);
       }
};
这是一个基本项,当您使用基本QGraphicsSitem和QGraphicscene时,它将移动

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QGraphicsScene scene;
        scene.addItem(new GraphicsItem(NULL));
        QGraphicsView view(&scene);
        view.show();

        return a.exec();
   }

如果代码中的问题似乎是您的项没有移动,则可能是您的MousePressEvent。

正如我们在注释中所确定的,问题是boundingRect()函数返回的值

QGraphicsItem的边界矩形定义项目的局部坐标。如果项是与矩形匹配的规则项,则只需实现boundingRect()。这用于碰撞检测,其中包括检测鼠标在项目上的情况


如果您有一个非规则(矩形)对象,并且需要更精确的碰撞检测,那么除了boundingRect()之外,还需要实现该函数。两者都位于项目的本地坐标中。

如果项目正确继承自QGraphicsItem,则只需实现纯虚拟函数并设置ItemIsMovable和ItemIsSelectable标志。使用常规的QGraphicsView和QGraphicsCenter,并将项目对象添加到场景中。如果你不能用鼠标移动物品,说明你做错了。在本例中,您需要显示更多的项代码,例如您是如何实现boundingRect()的我添加了boundingRect()-您是对的,这正是我所期望的。。。ohhh可能boundingRect必须在全局位置坐标而不是视口位置?但是当我签入MousePressed函数时,这两个版本都不起作用。不,boundingRect()必须位于项目的局部坐标中。因此,一个矩形返回,例如,(-10,-10,20,20)的中心将位于(0,0),宽度和高度为20。我已经尝试过了——在绘画中我使用了“画师->平移(x,y);”仍然对移动没有影响,并且我无法实现我自己的移动。请显示为您的项目类实现的代码。你为什么打电话给画家翻译?谢谢你。。。我的QGraphics网站之所以不能正常运行,是因为我对类的错误理解,以及我试图自己实现所有东西的事实