【问题标题】:Custom QGraphicsItem That Contains Child QGraphicsItems包含子 QGraphicsItems 的自定义 QGraphicsItem
【发布时间】:2019-05-14 16:16:48
【问题描述】:

我是 Qt 的新手,我想编写我的自定义 QGraphicsItem,其中包含一个矩形和几个按钮。我想编写一个可以轻松添加到 QGraphicsScene 并使用其中的内容(按钮和矩形)移动或调整大小的自定义组件。最后,我想将多个自定义 QGraphicsItem 添加到我的 QGraphicsScene 中。我的问题是如何编写这个包含按钮和矩形的自定义 QGraphicsItem,它们的相对位置是恒定的。

在此图中,绿色矩形代表按钮,它们彼此的相对位置始终保持不变(就像使用 qlayouts 放置它们一样)

【问题讨论】:

  • 用锚检查这个例子:doc.qt.io/qt-5/… 的一种方法。使用子项的另一种方法在这里:doc.qt.io/qt-5/…。您应该可以通过 Creator 在本地使用这两个示例。这些应该可以为您提供总体思路,如果您有更具体的问题,您可以返回。
  • doc.qt.io/qt-5/… 的@replete 拖放机器人示例对我帮助很大。非常感谢

标签: c++ qt qt5 qgraphicsscene qgraphicsitem


【解决方案1】:

感谢@replete,从http://doc.qt.io/qt-5/qtwidgets-graphicsview-dragdroprobot-example.html 的示例中,我能够创建一个自定义QGraphicsItem,其中包含可点击的子部分。在下面的代码中,BboxItem 代表容器 QGraphicsItem,BboxItemContent 代表它的子项。通过使用鼠标点击事件发出信号,我能够实现类似按钮的功能。我可以通过设置边界矩形来移动 BboxItem。

BboxItem相关源码:

BboxItemContent::BboxItemContent(QGraphicsItem *parent, int type, QColor color,QRectF *rect)
    : QGraphicsObject(parent)
{
    content_rectangle = rect;
    content_type = type;
    switch (type)
    {
    case 0:
        rectangle_color = color;
        icon = 0;
        break;
    case 1:
        icon = new  QImage(":/resource/assets/info_btn.png");
        break;
    case 2:
        icon = new  QImage(":/resource/assets/close_btn.png");
        break;
    }
}

BboxItemContent::~BboxItemContent()
{
    delete icon;
}

QRectF BboxItemContent::boundingRect() const
{
    return QRectF(content_rectangle->x(), content_rectangle->y(), content_rectangle->width(), content_rectangle->height());
}

void BboxItemContent::paint(QPainter *painter,
    const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    if (icon == 0)
    {
        QPen pen(rectangle_color, 3);
        painter->setPen(pen);
        painter->drawRect(*content_rectangle);

    }
    else
    {
        painter->drawImage(*content_rectangle, *icon);
    }
}

void BboxItemContent::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
    emit bboxContentClickedSignal();
}

void BboxItemContent::setRect(QRectF *rect)
{
    content_rectangle = rect;
    update();
}

BboxItem::BboxItem(QGraphicsItem *parent,QRectF *itemRect) : BboxItemContent(parent,0,Qt::red, itemRect)
{
    setFlag(ItemHasNoContents);
    bbox_area = new BboxItemContent(this, 0, Qt::red, itemRect);
    info_btn = new BboxItemContent(this, 1, Qt::red, new QRectF(itemRect->x() - 30, itemRect->y(), 30, 30));
    connect(info_btn, &BboxItemContent::bboxContentClickedSignal, this, &BboxItem::onInfoClickedSlot);
    delete_btn= new BboxItemContent(this, 2, Qt::red, new QRectF((itemRect->x()+itemRect->width()), itemRect->y(), 30, 30));
    connect(delete_btn, &BboxItemContent::bboxContentClickedSignal, this, &BboxItem::onDeleteClickedSlot);
}

void BboxItem::onDeleteClickedSlot()
{
    //delete clicked actions
}
void BboxItem::onInfoClickedSlot()
{
    //info clicked actions
}

void BboxItem::setRect(QRectF *rect)
{
    bbox_area->setRect(rect);
    info_btn->setRect(new QRectF(rect->x() - 30, rect->y(), 30, 30));
    delete_btn->setRect(new QRectF((rect->x() + rect->width()), rect->y(), 30, 30));
}

相关标题:

class BboxItemContent : public QGraphicsObject
{
    Q_OBJECT
public:
    BboxItemContent(QGraphicsItem *parent = 0, int type = 0, QColor color = Qt::red, QRectF *rect=nullptr);
    ~BboxItemContent();
    // Inherited from QGraphicsItem
    QRectF boundingRect() const override;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
    void setRect(QRectF *rect);
signals:
    void bboxContentClickedSignal();
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
private:
    QImage *icon;
    QColor rectangle_color;
    QRectF *content_rectangle;
    int content_type;
};

class BboxItem : public BboxItemContent {
    Q_OBJECT
public:
    BboxItem(QGraphicsItem *parent = 0,QRectF *itemRect=nullptr);
    void setRect(QRectF *rect);
private slots:
    void onDeleteClickedSlot();
    void onInfoClickedSlot();
private:
    BboxItemContent *delete_btn;
    BboxItemContent *bbox_area;
    BboxItemContent *info_btn;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    相关资源
    最近更新 更多