QT 5.7 QPainter线条对齐

3
我正在使用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();
}

线条在底部和右侧比其他地方要大:
problem
在有人告诉我必须删除两个-1表达式之前,您应该知道如果我这样做并且将笔宽度设置为1,那么底部和右侧就没有线条了。
problem
我认为这个伪像是由“线对齐”引起的。 QT试图着色与矩形定义的逻辑线附近的像素,但实际上因为最终所有像素都必须在像素中决定。 如果我是正确的,为什么没有方法可以像GDI +一样设置笔的线对齐方式? 我该如何解决这个问题?
1个回答

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"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接