2016-06-24 7 views
3

QT 5.7とC++で作業しています。 現時点では、私は自分のウィジェットをQPainterクラスで描画するのに慣れようとしています。 しかし私は解決できなかった問題に気づいた。 私はウィジェット国境でextactly境界線を描画しようとするが、私はそうする場合:QT 5.7 Qラインのアライメント

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

そして、誰かが私に2つを取り除かなければならないと言ってくる前に、-1式 私はこれを行い、ペンの幅を1に設定すると知っているはずです。
problem

私はこのアーティファクトは、 "ラインaligment" によって引き起こされていると思います。 QTは、矩形によって定義された論理行の近くのピクセルに色合いを付けることを試みますが、実際は最終的にはすべてがピクセルでなければならないため、決定する必要があります。 私が正しければ、なぜset the line aligment of the pen like in GDI+への方法がないのですか? どうすればこの問題を解決できますか?

答えて

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" 
関連する問題