QT 5.7 QPainter line aligment

时间:2016-06-24 18:23:03

标签: c++ qt qpainter

我正在使用QT 5.7和C ++。 目前我尝试习惯用QPainter类绘制自己的小部件。 但我注意到一个我无法解决的问题。 我尝试在小部件边框处直接绘制边界线但是如果我这样做:

void MyWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter;
    painter.begin(this);
    painter.setBrush(Qt::cyan);

    QBrush brush(Qt::black);
    QPen pen(brush, 2);

    painter.setPen(pen);
    painter.drawRect(0, 0, size().width() - 1, size().height() - 1);
    painter.end();
}

Line的底部和右侧站点比其他站点更大:
problem

在有人告诉我之前我必须删除两个 -1 表达式, 你应该知道我是否这样做,并将笔宽设置为1,在底部和右侧不再有线。
problem

我认为这个工件是由“ line aligment ”引起的。 QT试图对矩形定义的逻辑线附近的像素进行着色,但实际上因为最终所有必须以像素为单位决定。 如果我是对的,为什么set the line aligment of the pen like in GDI+没有方法? 我怎么解决这个问题?

1 个答案:

答案 0 :(得分:1)

一切都取决于您是否希望整个笔的宽度可见。通过从0,0开始绘制矩形,您只显示笔宽度的一半,这会使事情变得不必要地复杂化 - 更别提这条线看起来太薄了。在Qt中,非化妆笔总是与线条的中间对齐。 Qt不允许你改变它:你可以改变绘制的几何形状。

为了使奇数线尺寸正确,您必须将矩形坐标作为浮点值,并且它们必须落在线的中间。所以,例如如果笔的宽度为3.0个单位,则矩形的几何图形将为(1.5, 1.5, width()-3.0, width()-3.0)

这是一个完整的例子:

// https://github.com/KubaO/stackoverflown/tree/master/questions/widget-pen-wide-38019846
#include <QtWidgets>

class Widget : public QWidget {
   Q_OBJECT
   Q_PROPERTY(qreal penWidth READ penWidth WRITE setPenWidth)
   qreal m_penWidth = 1.0;
protected:
   void paintEvent(QPaintEvent *) override {
      QPainter p{this};
      p.setPen({Qt::black, m_penWidth, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin});
      p.setBrush(Qt::cyan);
      qreal d = m_penWidth/2.0;
      p.drawRect(QRectF{d, d, width()-m_penWidth, height()-m_penWidth});
   }
public:
   explicit Widget(QWidget * parent = 0) : QWidget{parent} { }
   qreal penWidth() const { return m_penWidth; }
   void setPenWidth(qreal width) {
      if (width == m_penWidth) return;
      m_penWidth = width;
      update();
   }
   QSize sizeHint() const override { return {100, 100}; }
};

int main(int argc, char ** argv) {
   QApplication app{argc, argv};
   QWidget top;
   QVBoxLayout layout{&top};
   Widget widget;
   QSlider slider{Qt::Horizontal};
   layout.addWidget(&widget);
   layout.addWidget(&slider);

   slider.setMinimum(100);
   slider.setMaximum(1000);
   QObject::connect(&slider, &QSlider::valueChanged, [&](int val){
      widget.setPenWidth(val/100.0);
   });

   top.show();
   return app.exec();
}

#include "main.moc"