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 do you center QGraphicsTextItem in its parent?
Forum Updated to NodeBB v4.3 + New Features

How do you center QGraphicsTextItem in its parent?

Scheduled Pinned Locked Moved Unsolved General and Desktop
2 Posts 1 Posters 1.2k Views 1 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

    Right now it centers horizontally:

    x1.gif

    with these in PieView:

    PieView::PieView(QWidget *parent) : QGraphicsView(parent){
        auto scene = new QGraphicsScene(this);
        setScene(scene);
        setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ellipse = new QGraphicsEllipseItem();
        ellipse->setBrush(Qt::white);
        ellipse->setPen(Qt::NoPen);
        ellipse->setAcceptHoverEvents(false);
        text = new QGraphicsTextItem(ellipse);
        text->setAcceptHoverEvents(false);
        connect(this, &PieView::mouseOver, this, &PieView::onMouseOver);
        connect(this, &PieView::mouseLeave, this, &PieView::onMouseLeave);
    }
    void PieView::resizeEvent(QResizeEvent*){
        fitInView(scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
        centerOn(0, 0);
    }
    void PieView::onMouseOver(PieSeries &s){
        text->document()->clear();
        auto cursor = QTextCursor(text->document());
        QTextBlockFormat blockFormat;
        QTextCharFormat charFormat;
    
        blockFormat.setAlignment(Qt::AlignCenter | Qt::AlignVCenter);
        charFormat.setForeground(Qt::darkGreen);
        charFormat.setFontPointSize(16);
        cursor.setBlockFormat(blockFormat);
        cursor.setBlockCharFormat(charFormat);
        cursor.insertText(s.name);
    
        charFormat.setForeground(Qt::red);
        charFormat.setFontPointSize(14);
        cursor.insertBlock(blockFormat, charFormat);
        cursor.insertText(QString::number(s.value));
    
        charFormat.setForeground(Qt::black);
        charFormat.setFontPointSize(12);
        cursor.insertBlock(blockFormat, charFormat);
        cursor.insertText(QString::number(s.value / m_total * 100) + "%");
        scene()->addItem(ellipse);
    }
    void PieView::onMouseLeave(){ scene()->removeItem(ellipse); }
    void PieView::makePie(QVector<PieSeries>& series){
        scene()->clear();
        m_total = 0;
        float startAngle = 0, spanAngle;
        for (int i = 0; i < series.size(); i++) m_total += series[i].value;
        QRandomGenerator rand;
        auto rect = QRectF(0,0, 200,200);
        for (int i = 0; i < series.size(); i++){
            spanAngle = series[i].value / m_total * 360;
            auto color = QColor::fromRgb(rand.global()->bounded(0,255), rand.global()->bounded(0,255), rand.global()->bounded(0,255));
            auto slice = new Slice(startAngle, spanAngle, color, rect, series[i]);
            scene()->addItem(slice);
            startAngle += spanAngle;
        }
        auto eRect = QRectF(QPoint(sceneRect().center().x() - 75, sceneRect().center().y() - 75), QSize(150,150));
        ellipse->setRect(eRect);
        text->setTextWidth(rect.width());
    }
    

    it also moves the whole scene first time. When I first hover over the first slice, those two other slices moved. Here's what is in Slice, QGraphicsItem, right now:

    #define whats16 16
    Slice::Slice(float start, float sweep, QColor color, QRectF rect, PieSeries& series)
        : m_start(start), m_sweep(sweep), m_color(color), m_series(series){
        m_realColor = color;
        m_rect = rect;
        m_path = QPainterPath(QPointF(m_rect.width() / 2, m_rect.height() / 2));
        m_path.arcTo(m_rect, -m_start, -m_sweep);
        m_path.closeSubpath();
        dx = 10 * cos((m_start + m_sweep / 2) * M_PI / 180);
        dy = 10 * sin((m_start + m_sweep / 2) * M_PI / 180);
        float dimension = m_rect.width() + 2 * 20;
        m_boundingRect = QRectF(-20, -20, dimension, dimension);
        setAcceptHoverEvents(true);
    }
    QRectF Slice::boundingRect() const { return m_boundingRect; }
    QPainterPath Slice::shape() const { return m_path;}
    void Slice::hoverEnterEvent(QGraphicsSceneHoverEvent*){
        m_color = Qt::gray;
        moveBy(dx, dy);
        auto view = static_cast<PieView*>(scene()->parent());
        emit view->mouseOver(m_series);
    }
    void Slice::hoverLeaveEvent(QGraphicsSceneHoverEvent*){
        m_color = m_realColor;
        moveBy(-dx, -dy);
        auto view = static_cast<PieView*>(scene()->parent());
        emit view->mouseLeave();
    }
    void Slice::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*){
        painter->setRenderHint(QPainter::Antialiasing);
        painter->setPen(Qt::NoPen);
        painter->setBrush(m_color);
        painter->drawPie(m_rect, whats16 * -m_start, whats16 * -m_sweep);
    }
    

    in main window, I've a QComboBox and PieView in a QVboxLayout:

    Window::Window(QWidget *parent) : QWidget(parent){
        auto combo = new QComboBox(this);
        combo->addItems(QStringList() << "6" << "3");
        pie = new PieView(this);
        pie->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        auto lay = new QVBoxLayout(this);
        lay->setContentsMargins(0,0,0,0);
        lay->addWidget(combo);
        lay->addWidget(pie);
        setLayout(lay);
        connect(combo, &QComboBox::currentIndexChanged, this, &Window::oSelectionChanged);
        combo->setCurrentIndex(1);
    }
    void Window::oSelectionChanged(int index){
        QVector<PieSeries> series;
        if(index == 0){
            series.append(PieSeries("Series 1", 100));
            series.append(PieSeries("Series 2", 200));
            series.append(PieSeries("Series 3", 300));
            series.append(PieSeries("Series 4", 150));
            series.append(PieSeries("Series 5", 225));
            series.append(PieSeries("Series 6", 275));
        }
        else if(index == 1){
            series.append(PieSeries("Series 2", 200));
            series.append(PieSeries("Series 3", 300));
            series.append(PieSeries("Series 4", 150));
        }
        pie->makePie(series);
    }
    

    PieSeries is a struct with these:

    struct PieSeries{
        QString name;
        float value;
        PieSeries(QString name, float value){
            this->name = name;
            this->value = value;
        }
    };
    
    1 Reply Last reply
    0
    • D Offline
      D Offline
      deleted385
      wrote on last edited by deleted385
      #2

      For the text alignment, this setY

      ...
      text->setY(ellipse->boundingRect().center().y() - text->boundingRect().height()/2);
      scene()->addItem(ellipse);
      

      in void PieView::onMouseOver(PieSeries &s) works:

      x2.gif

      Still couldn't figure out why the remaining slices moves once or more when I first start hovering over slices

      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