pennyBoy
pennyBoy

Reputation: 397

How to center a QLine

How does one center a vertical QLine in the center of my horizontal QLine to form a cross. My current implementation does not center the vertical line appropriately.

void crossWidget::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);
    painter.setPen(QPen(Qt::black, Qt::SolidLine));
    QLine originLine;
    int width = parent->width();
    int height = parent->height();

    originLine.setP1(QPoint(-width, 0));
    originLine.setP2(QPoint(width, 0));
    originLine.setLine( -(width / 2), 0, width / 2, 0);
    painter.drawLine(originLine);

    painter.setPen(QPen(Qt::black, Qt::DashLine));
    QLine originHLine;
    originHLine.setP1(QPoint(0, -height));
    originHLine.setP2(QPoint(0, height));
    originHLine.setLine(
        originLine.center().x(),
        originLine.center().y() - (height / 2) ,
        originLine.center().x(), 
        originLine.center().y() + (height / 2));
    painter.drawLine(originHLine);
    
}

Upvotes: 0

Views: 349

Answers (2)

Scheff's Cat
Scheff's Cat

Reputation: 20141

I wonder why that complicated…

#include <QtWidgets>

class CrossWidget: public QWidget {

  public:
    CrossWidget(QWidget* pQParent = nullptr):
      QWidget(pQParent)
    { }

    virtual ~CrossWidget() = default;

    CrossWidget(const CrossWidget&) = delete;
    CrossWidget& operator=(const CrossWidget&) = delete;

  protected:
    virtual void paintEvent(QPaintEvent* pQEvent) override;
};

void CrossWidget::paintEvent(QPaintEvent* pQEvent)
{
  const int w = width(), h = height();
  const int wH = w / 2, hH = h / 2;
  QPainter qPainter(this);
  qPainter.drawLine(0, hH, w, hH);
  qPainter.drawLine(wH, 0, wH, h);
}

int main(int argc, char** argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  CrossWidget qWinMain;
  qWinMain.show();
  // runtime loop
  return app.exec();
}

Output:

snapshot (GIF Animation)


OP pointed out that the layout may shrink the CrossWidget that it makes it effectively invisible. To prevent this, the sizeHint() may be overloaded:

#include <QtWidgets>

class CrossWidget: public QWidget {

  public:
    CrossWidget(QWidget* pQParent = nullptr):
      QWidget(pQParent)
    { }

    virtual ~CrossWidget() = default;

    CrossWidget(const CrossWidget&) = delete;
    CrossWidget& operator=(const CrossWidget&) = delete;

  protected:
    virtual QSize sizeHint() const override { return QSize(20, 20); }

    virtual void paintEvent(QPaintEvent* pQEvent) override;
};

void CrossWidget::paintEvent(QPaintEvent* pQEvent)
{
  const int w = width(), h = height();
  const int wH = w / 2, hH = h / 2;
  QPainter qPainter(this);
  qPainter.drawLine(0, hH, w, hH);
  qPainter.drawLine(wH, 0, wH, h);
}

int main(int argc, char** argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  QWidget qWinMain;
  QHBoxLayout qHBox;
  QLabel qLbl("A cross widget:");
  qHBox.addWidget(&qLbl, 1);
  CrossWidget qCross;
  qHBox.addWidget(&qCross);
  qWinMain.setLayout(&qHBox);
  qWinMain.show();
  // runtime loop
  return app.exec();
}

Output:

Snapshot of the MCVE

Upvotes: 4

To draw a cross you need the middle point of the canvas geometry...

your horizontal line (red one) will split your canvas into 2 identical shapes, 1 above the other.. so you need the middle point in the y axis. analog to this, your vertical line (blue one) will split the canvas in t identical pieces, so you need the middle point in the x axis.

in qt you can draw a line by giving the origin and end point

so you need something like

drawLine(0, H/2, W, H/2);

and this will draw the red line for example...

see my ref picture:

enter image description here

Upvotes: 3

Related Questions