Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to remove extra space around QGraphicsItem and round top corners of Rectangle?
Forum Updated to NodeBB v4.3 + New Features

How to remove extra space around QGraphicsItem and round top corners of Rectangle?

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 276 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    deleted385
    wrote on last edited by deleted385
    #1

    Here's what I've in the Bar, QGraphicsItem:

    Bar::Bar(QRectF rect, BarSeries& s, float max, QGraphicsItem *parent)
        : QGraphicsItem(parent), m_rect(rect), m_series(s), m_max(max){ }
    QRectF Bar::boundingRect() const { return m_rect; }
    void Bar::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *){
        painter->setRenderHints(QPainter::Antialiasing);
        painter->setBrush(Qt::black);
        painter->setPen(Qt::white);
        painter->translate(0, m_rect.height());
        painter->scale(1.0, -1.0);
        float h1 = m_series.value1 / m_max * m_rect.height();
        float h2 = m_series.value2 / m_max * m_rect.height();
        auto rect = QRectF(m_rect.left(), 0, m_rect.width(), h1);
        painter->drawRect(rect);
        painter->setBrush(Qt::gray);
        rect = QRectF(m_rect.left(), h1, m_rect.width(), h2);
        //painter->drawRoundedRect(rect, 0, 5); // tried this to round only top corners
        painter->drawRect(rect);
    }
    

    and here's how it looks:

    x1.gif

    it adds some extra spaces around those rectangles. How to remove those extra spaces and round only top corners of these rectangles? In the BarView, QGraphicsView, I add Bar in the scene with these:

    BarView::BarView(QWidget *parent) : QGraphicsView(parent), m_spacing(5){
        setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        auto scene = new QGraphicsScene(this);
        scene->setSceneRect(0,0,200,200);
        setScene(scene);
    }
    void BarView::fit(){
        fitInView(scene()->itemsBoundingRect());
        centerOn(0,0);
    }
    void BarView::resizeEvent(QResizeEvent*){ fit(); }
    void BarView::addBars(QVector<BarSeries>& series){
        scene()->clear();
        float max = 0, start = 0, total;
        for (int i = 0; i < series.size(); i++) {
            total = series[i].value1 + series[i].value2;
            if(max < total) max = total;
        }
        auto rect = sceneRect();
        auto barWidth = rect.width() / series.size() - series.size() * m_spacing - m_spacing;
        for (int i = 0; i < series.size(); i++) {
            //auto proportion = (series[i].value1 + series[i].value2) / max * rect.height();
            auto barRect = QRectF(start, rect.top(), barWidth, rect.height());
            auto bar = new Bar(barRect, series[i], max);
            scene()->addItem(bar);
            start += m_spacing + barWidth;
        }
        fit();
    }
    

    and in the Window I've these:

    Window::Window(QWidget *parent) : QWidget(parent){
        auto lay = new QVBoxLayout(this);
        setLayout(lay);
        auto combo = new QComboBox(this);
        combo->addItems(QStringList() << "4" << "5");
        barChart = new BarView(this);
        barChart->setFrameShape(QFrame::Box);
        lay->addWidget(combo);
        lay->addWidget(barChart);
        connect(combo, &QComboBox::currentIndexChanged, this, &Window::onSelectionChanged);
        combo->setCurrentIndex(1);
    }
    Window::~Window(){}
    void Window::onSelectionChanged(int index){
        QVector<BarSeries> series;
        series.append(BarSeries("S1", 100, 100));
        series.append(BarSeries("S2", 200, 100));
        series.append(BarSeries("S3", 300, 100));
        series.append(BarSeries("S4", 200, 0));
        if(index == 1) series.append(BarSeries("S5", 100, 50));
        barChart->addBars(series);
    }
    

    and BarSeries is a struct:

    struct BarSeries{
        QString name;
        float value1;
        float value2;
        BarSeries(const QString& name, float value1, float value2){
            this->name = name;
            this->value1 = value1;
            this->value2 = value2;
        }
    };
    

    EDIT
    with painter->setPen(Qt::NoPen); in Bar the white space between stacked rectangles is removed BUT feels like it still adds some extra space around the whole GraphicsItem. In WPF I used SnapsToDevicePixel, is there anything like that?

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mchinand
      wrote on last edited by
      #2

      I think you could have also fixed the extra space issue by accounting for the pen width when computing the boundingRect of your Bar QGraphicsItem class; see the note here.

      D 1 Reply Last reply
      1
      • M mchinand

        I think you could have also fixed the extra space issue by accounting for the pen width when computing the boundingRect of your Bar QGraphicsItem class; see the note here.

        D Offline
        D Offline
        deleted385
        wrote on last edited by
        #3

        @mchinand, for the pie, I used that technique to put some extra margin around the pie. In this case I, probably, would have to use the boundingRect instead of m_rect, in paint, to get the desired output.

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved