Пользовательский QGraphicsItem, который содержит дочерние QGraphicsItems - PullRequest
0 голосов
/ 13 декабря 2018

Я новичок в Qt и хочу написать свой собственный QGraphicsItem, который содержит прямоугольник и пару кнопок.Я хочу написать один пользовательский компонент, который можно было бы легко добавить в QGraphicsScene и переместить или изменить размер содержимого (кнопок и прямоугольников) в нем.В конце я хочу добавить несколько пользовательских QGraphicsItem к моей QGraphicsScene.Мой вопрос заключается в том, как мне написать этот настроенный QGraphicsItem, который содержит кнопки и прямоугольники, относительные позиции которых относительно друг друга являются постоянными.

На этом чертеже прямоугольники зеленого цвета представляют кнопки, и их относительное положение всегда остается неизменным (как если бы они были размещены с использованием qlayouts)

1 Ответ

0 голосов
/ 13 декабря 2018

Благодаря @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;
};
...