4

QDialog に丸みを帯びた角を設定したい。これはトップレベルのウィンドウであるため、border-radius が機能しないため、次のようにする必要があります。

QRegion EnterPinDialog::roundedRect(const QRect& rect, int r)
{
    QRegion region;

    // middle and borders
    region += rect.adjusted(r, 0, -r, 0);
    region += rect.adjusted(0, r, 0, -r);

    // top left
    QRect corner(rect.topLeft(), QSize(r*2, r*2));
    region += QRegion(corner, QRegion::Ellipse);

    // top right
    corner.moveTopRight(rect.topRight());
    region += QRegion(corner, QRegion::Ellipse);

    // bottom left
    corner.moveBottomLeft(rect.bottomLeft());
    region += QRegion(corner, QRegion::Ellipse);

    // bottom right
    corner.moveBottomRight(rect.bottomRight());
    region += QRegion(corner, QRegion::Ellipse);

    return region;
}

そして私はそれをこのように呼びます:

this->setMask(roundedRect(this->rect(), 8));

動作しますが、問題は角がピクセル化されることです。

これらのピクセル化された角を持たずにそれを取得する方法はありますか? はいの場合、どのように?

4

3 に答える 3

2

このパーティーにはちょっと遅れましたが、他の誰かを助けるかもしれません. これは、新しい QBitmap の上に描画することにより、ピクセル化の少ないマスクを作成する方法を示しています (ビットマップには 2 色しかないため、実際にはまだアンチエイリアス処理されていませんが、曲線は QPainterPath を直接使用するよりもはるかに滑らかです)。

私の場合、メイン ウィンドウ内に (中央のウィジェットとして) 配置されたウィジェットの形状をマスクしたかったのです。4 つの端に 4 つのツールバーがあり、中央のビューの境界線を丸くし、メイン ウィンドウの背景が透けて見えるようにしました。Harald が提案するように、これは CSS 経由では実行できませんでした。これは、ウィジェットのコンテンツが実際には丸い境界線に収まらないためです。

// MainView is simply a QWidget subclass.
void MainView::resizeEvent(QResizeEvent *event)
{
    QBitmap bmp(size());
    bmp.clear();
    QPainter painter(&bmp);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(QColor(Qt::black));
    painter.setBrush(QColor(Qt::black));
    painter.drawRoundedRect(geometry(), 20.0f, 20.0f, Qt::AbsoluteSize);
    setMask(bmp);
}

現在のウィジェットのサイズを知る必要があるため ( と を使用)、resizeEvent にありsize()ますgeometry()。これは元の投稿の短い代替案です (私が思うに) が、丸みを帯びたエッジはピクセル化されます。

void MainView::resizeEvent(QResizeEvent *event)
{
    QPainterPath path;
    path.addRoundedRect(geometry(), 20.0f, 20.0f, Qt::AbsoluteSize);
    QRegion region = QRegion(path.toFillPolygon().toPolygon());
    setMask(region);
}
于 2014-03-26T04:55:20.523 に答える
1

ここに示されているsetAttribute( Qt.WA_TranslucentBackground, True)メソッド も機能します... トップレベル ウィンドウでこの属性を設定し、 paintEvent()メソッド オーバーライドで QPainterPath を使用してウィンドウの形状をペイントします。

角の丸い四角形の QPainterPath を作成またはペイントするのに役立つ(python)コードを次に示します。

def drawPartiallyRoundedRect(painter,x,y,w,h, 
                             radiusTR, radiusBR, radiusBL, radiusTL,
                             doFill,fillColor,
                             doLine=False,lineColor=None,lineWidth=1,
                             antiAlias=True):


    w2 = int(w/2.0)
    h2 = int(h/2.0)


    if (doLine):
        x += lineWidth/2.0
        y += lineWidth/2.0
        w -= lineWidth
        h -= lineWidth


    T = y
    L = x
    R = x + w
    B = y + h

    # clamp values to fit within rect
    if (radiusTR > w2):
        radiusTR = w2
    if (radiusTR > h2):
        radiusTR = h2

    if (radiusTL > w2):
        radiusTL = w2
    if (radiusTL > h2):
        radiusTL = h2

    if (radiusBL > w2):
        radiusBL = w2
    if (radiusBL > h2):
        radiusBL = h2

    if (radiusBR > w2):
        radiusBR = w2
    if (radiusBR > h2):
        radiusBR = h2

    diamTR  = radiusTR + radiusTR
    diamBR  = radiusBR + radiusBR
    diamBL  = radiusBL + radiusBL
    diamTL  = radiusTL + radiusTL

    p = QPainterPath()
    if (radiusTR > 0.0):
        p.moveTo(R, T + radiusTR);
        p.arcTo(R-diamTR, T, diamTR, diamTR, 0.0, 90.0)  # TR
    else:
        p.moveTo(R,T)

    if (radiusTL > 0.0):
        p.arcTo(L, T, diamTL, diamTL, 90.0, 90.0)  # TL
    else:
        p.lineTo(L,T)

    if (radiusBL > 0.0):
        p.arcTo(L, B-diamBL, diamBL, diamBL, 180.0, 90.0);  # BL
    else:
        p.lineTo(L,B)

    if (radiusBR > 0.0):
        p.arcTo(R-diamBR, B-diamBR, diamBR, diamBR, 270.0, 90.0);  # BR
    else:
        p.lineTo(R,B)

    p.closeSubpath();

    if (antiAlias):
        painter.setRenderHint(QPainter.Antialiasing,True)
    else:
        painter.setRenderHint(QPainter.Antialiasing,False)

    if (doFill and fillColor):
        painter.setBrush( fillColor )
    elif ( doFill ): # pass doFill and None for fillColor to use current brush
        pass
    else:
        painter.setBrush( Qt.NoBrush )

    if ((lineWidth != 0.0) and doLine and lineColor):
        pen = QPen( lineColor, lineWidth,
                    Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin )
        painter.setPen( pen )
    else:
        painter.setPen( Qt.NoPen )

    painter.drawPath( p )
于 2012-01-04T09:21:07.783 に答える
0

ダイアログの外観に応じて、css を介してトップレベル ウィンドウのスタイルを完全に変更できます。スタイルシートのドキュメント全体を参照してください。

border: 2px; border-radius 2px;

半径 2 ピクセルの幅 2 ピクセルの境界線が表示されます。

一般に、スタイルシートを使用して、UI のカスタマイズのニーズのほとんどを処理できるはずです。

于 2010-09-30T09:48:06.153 に答える