Я пытаюсь создать границу градиентного цвета для кнопки во всплывающем окне. Кажется, хорошо, если я не буду пытаться центрировать всплывающее окно. У меня нет слов, чтобы назвать имя или описать проблему. Пожалуйста, обратите внимание на рамку кнопки «Отмена» на прикрепленном изображении и на код. (Я использую Qt 6.3)
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
//import QtQuick3D
import Qt5Compat.GraphicalEffects
ApplicationWindow {
id: root
width: 666
height: 777
visible: true
color: "grey"
Button
{
width: 111
height: 44
text: "Show"
onClicked: menu.open()
}
Popup {
id: menu
width: (559)
height: (643)
modal: true
dim: false
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
background: Rectangle {
// color: "transparent"
border.color: "transparent"
LinearGradient {
anchors.fill: parent
start: Qt.point(0, 0)
end: Qt.point(0, parent.height)
gradient: Gradient {
GradientStop { position: 0.0; color: "#29395D" }
GradientStop { position: 1.0; color: "#1C2341" }
}
}
}
// Component.onCompleted: {
// x: (parent.width - width) / 2
// y: (parent.height - height) / 2
//// anchors.centerIn = parent
//// anchors.centerIn = Overlay.overlay
// }
// onAboutToShow: anchors.centerIn = Overlay.overlay
anchors.centerIn : Overlay.overlay
Button {
id: okBt
anchors.top: parent.top
anchors.topMargin: (410)
anchors.horizontalCenter: parent.horizontalCenter
width: (276)
height: (41)
text: "OK"
// font.family: FontModel.family
font.pixelSize: (16)
font.weight: Font.Normal //400
contentItem: Text {
text: parent.text
font: parent.font
color: "#FFFFFF"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
flat: true
background: Rectangle {
implicitWidth: (276)
implicitHeight: (41)
radius: (6)
border.width: 0
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 1.0; color: "#2F3D6D" }
GradientStop { position: 0.0; color: "#3C5199" }
}
}
}
Button {
id: cancelBt
// visible: false
anchors.top: parent.top
anchors.topMargin: (471)
anchors.horizontalCenter: parent.horizontalCenter
width: (276)
height: (41)
text: "Cancel"
// font.family: FontModel.family
font.pixelSize: (16)
font.weight: Font.Normal //400
contentItem: Text {
text: parent.text
font: parent.font
color: "#FFFFFF"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
flat: true
}
Rectangle {
id: gradientBorder
anchors.top: parent.top
anchors.topMargin: (471)
anchors.horizontalCenter: parent.horizontalCenter
width: (276)
height: (41)
radius: (6)
z: cancelBt.z + 11
color: "transparent"
Rectangle {
id: bd
anchors.fill: parent
radius: parent.radius
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 1.0; color: "#2F3D6D" }
GradientStop { position: 0.0; color: "#3C5199" }
}
layer.enabled: true
layer.effect: OpacityMask {
invert: true
maskSource: Item {
width: bd.width
height: bd.height
Rectangle {
anchors.centerIn: parent
width: parent.width -2
height: parent.height -2
radius: gradientBorder.radius
}
}
}
}
}
}
}
@iam_peter: проблема все еще существует.
Проблема, с которой вы столкнулись, определенно связана с округлением на полпикселя. Это особенно проблема при использовании текстур/слоев, поскольку внутренний размер текстур (sourceSize
) округляется при создании текстур из элементов, позиционированных/размерных с плавающей запятой. Я не внимательно рассмотрел ваш пример, когда создавал свой комментарий.
Чтобы обойти эту проблему, вам следует настроить размеры так, чтобы элементы были выровнены по пикселям. В моем примере ниже я уравнял все ваши нечетные размеры, чтобы логика привязки не размещала элементы на половине пикселя.
Также вместо OpacityMask
для создания выреза я использовал LinearGradient
из Qt5Compat.GraphicalEffects
и невидимый Rectangle
, который назначается как source
.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
ApplicationWindow {
id: root
width: 666
height: 777
visible: true
color: "grey"
Button {
width: 111
height: 44
text: qsTr("Show")
onClicked: popup.open()
anchors.centerIn: parent
}
Popup {
id: popup
width: 560
height: 644
modal: true
dim: false
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
anchors.centerIn : Overlay.overlay
background: Rectangle {
border.color: "transparent"
LinearGradient {
anchors.fill: parent
start: Qt.point(0, 0)
end: Qt.point(0, parent.height)
gradient: Gradient {
GradientStop { position: 0.0; color: "#29395D" }
GradientStop { position: 1.0; color: "#1C2341" }
}
}
}
Button {
id: okBt
anchors.top: parent.top
anchors.topMargin: 410
anchors.horizontalCenter: parent.horizontalCenter
width: 276
height: 42
text: qsTr("OK")
font.pixelSize: 16
font.weight: Font.Normal
flat: true
contentItem: Text {
text: parent.text
font: parent.font
color: "#FFFFFF"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: okBt.width
implicitHeight: okBt.height
radius: 6
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 1.0; color: "#2F3D6D" }
GradientStop { position: 0.0; color: "#3C5199" }
}
}
}
Button {
id: cancelBt
anchors.top: parent.top
anchors.topMargin: 471
anchors.horizontalCenter: parent.horizontalCenter
width: 276
height: 42
text: qsTr("Cancel")
font.pixelSize: 16
font.weight: Font.Normal
flat: true
contentItem: Text {
text: parent.text
font: parent.font
color: "#FFFFFF"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
Rectangle {
id: dummy
width: cancelBt.width
height: cancelBt.height
color: "transparent"
border.width: 2
radius: 6
visible: false
}
background: LinearGradient {
anchors.centerIn: parent
//anchors.alignWhenCentered: false
width: dummy.width
height: dummy.height
start: Qt.point(0, 0)
end: Qt.point(dummy.width, 0)
source: dummy
gradient: Gradient {
GradientStop { position: 1.0; color: "#2F3D6D" }
GradientStop { position: 0.0; color: "#3C5199" }
}
}
}
}
}
Я предполагаю, что это проблема половинного и полного выравнивания пикселей. Попробуйте установить
anchors.alignWhenCentered: false
на кнопку doc.qt.io/qt-6/…