如何在QGraphicsView上创建类似选项卡或缎带标签?

huangapple go评论91阅读模式
英文:

How to make a tab-like or ribbon-like label on a QGraphicsView?

问题

A good way to create a ribbon-like label for displaying text in a QGraphicsView, which contains a QGraphicsScene, is to use a QGraphicsItem or QGraphicsWidget for the ribbon. You can position it at the bottom of the view by setting its coordinates accordingly. This will make it independent of scene transformations and appear to "float above" the scene.

你可以在QGraphicsView中使用一个QGraphicsItem或QGraphicsWidget来创建一个类似于丝带的标签,然后通过设置它的坐标位置在视图底部,从而使其与场景的变换独立,看起来就像"漂浮"在场景之上。

英文:

What would be a good way to create a ribbon-like label for displaying text in a QGraphicsView which contains a QGraphicsScene such that the ribbon "floats above" the scene? i.e. is independent of the translation and other transformations of the scene and remains fixed at the bottom of the view.

I want to implement such a ribbon as a sort of status line to indicate when the application is in a modal state, but don't know if it's possible to do easily. (If it's not I'll think of something else) I don't need code just a general idea of how to approach this.

如何在QGraphicsView上创建类似选项卡或缎带标签?

答案1

得分: 0

以下是翻译好的部分:

"An easy way to do this is to override drawForeground in a custom scene. The trick is that drawForeground will be passed a QPainter that is set up to draw in scene coordinates but we want to draw in coordinates relative to the widget rectangle of the view, to do this you can simply set the painter's transform to the identity matrix."

"Code below. I call the content rectangle of the view minus the area taken up by any scroll bars 'the client rectangle' (because this is what it would be called in Win32) beyond that this code assumes that the custom scene is in one and only one view and the scene has getters/setters for showing/hiding a ribbon called 'the status line'."

"以下是代码示例。我将视图的内容矩形减去任何滚动条占用的区域称为 '客户区矩形'(因为在 Win32 中通常这样称呼),除此之外,此代码假定自定义场景仅存在一个视图,并且场景具有用于显示/隐藏称为 '状态行' 的带的 getter/setter。"

// ...

QRect client_rectangle(const QGraphicsView* view) {
    auto view_rect = view->contentsRect();
    if (view->verticalScrollBar()->isVisible()) {
        auto wd = view_rect.width();
        view_rect.setWidth(wd - view->verticalScrollBar()->width());
    }
    if (view->horizontalScrollBar()->isVisible()) {
        auto hgt = view_rect.height();
        view_rect.setHeight(hgt - view->horizontalScrollBar()->height());
    }
    return view_rect;
}

// ...

void MyCustomGraphicsScene::drawForeground(QPainter* painter, const QRectF& rect) {
    QGraphicsScene::drawForeground(painter, rect);

    if (is_status_line_visible()) {
        QGraphicsView* view = views().first();
        if (!view) {
            return;
        }

        painter->setTransform(QTransform());

        auto view_rect = client_rectangle(view);
        QRect ribbon_rect = {
            view_rect.bottomLeft() - QPoint(0, 35),
            QSize(view_rect.width(), 35)
        };
        painter->fillRect(ribbon_rect, Qt::yellow);
        painter->setPen(Qt::black);
        painter->drawText(ribbon_rect, Qt::AlignRight | Qt::AlignVCenter, status_line_);

        painter->resetTransform();
    }
}

请注意,以上是原文的翻译。

英文:

An easy way to do this is to override drawForeground in a custom scene. The trick is that drawForeground will be passed a QPainter that is set up to draw in scene coordinates but we want to draw in coordinates relative to the widget rectangle of the view, to do this you can simply set the painter's transform to the identity matrix.

Code below. I call the content rectangle of the view minus the area taken up by any scroll bars "the client rectangle" (because this is what it would be called in Win32) beyond that this code assumes that the custom scene is in one and only one view and the scene has getters/setters for showing/hiding a ribbon called "the status line".
<!-- language: C++ -->
// ...

QRect client_rectangle(const QGraphicsView* view) {
    auto view_rect = view-&gt;contentsRect();
    if (view-&gt;verticalScrollBar()-&gt;isVisible()) {
        auto wd = view_rect.width();
        view_rect.setWidth(wd - view-&gt;verticalScrollBar()-&gt;width());
    }
    if (view-&gt;horizontalScrollBar()-&gt;isVisible()) {
        auto hgt = view_rect.height();
        view_rect.setHeight(hgt - view-&gt;horizontalScrollBar()-&gt;height());
    }
    return view_rect;
}

// ...

void MyCustomGraphicsScene::drawForeground(QPainter* painter, const QRectF&amp; rect) {
    QGraphicsScene::drawForeground(painter, rect);

    if (is_status_line_visible()) {
        QGraphicsView* view = views().first();
        if (!view) {
            return;
        }

        painter-&gt;setTransform(QTransform());

        auto view_rect = client_rectangle(view);
        QRect ribbon_rect = {
            view_rect.bottomLeft() - QPoint(0, 35),
            QSize(view_rect.width(), 35)
        };
        painter-&gt;fillRect(ribbon_rect, Qt::yellow);
        painter-&gt;setPen(Qt::black);
        painter-&gt;drawText(ribbon_rect, Qt::AlignRight | Qt::AlignVCenter, status_line_);

        painter-&gt;resetTransform();
    }
}

huangapple
  • 本文由 发表于 2023年6月15日 07:00:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76478083.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定