I have a centered rectangle with a drop shadow behind it and some text within it.
import QtQuick 2.5
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0
Window {
visible: true
width: 800; height: 640
Rectangle{
id: centerRect
width: parent.width * 0.7; height: parent.height * 0.7
anchors{
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
radius: 7
border.color: "#C0C0C0"
Text{
text: "Hello World!"
font.pixelSize: 0.07 * parent.height
anchors{
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
}
}
DropShadow
{
anchors.fill: centerRect
horizontalOffset: 1; verticalOffset: 1
radius: 5
samples: 11
color: "#CDCDCD"
source: centerRect
}
}
When I resize the window the text becomes slightly blurred or out of focus. I thought it may have been an issue with how I'm scaling the font pixel size to the rectangle height but the problem is the same with static values. If I remove the drop shadow effect the text's visibility is fine when I resize the window.
How can I maintain good text visibility when using a drop shadow and resizing the window? I'm using Qt 5.5.1 on OpenSUSE Leap 42.1 (Plasma 5.5.5).
Solution 1: Use DropShadow only for the background rectangle and draw the text on top of that.
Solution 2: Use integral width and height for the centerRect. The graphical effect renders the centerRect first into a texture. If the source width or height are not integers, the texture size will not correspond to the original item size. When painting the texture, texture coordinates will not hit the pixel positions accurately and some interpolation is needed.
For me, the simplest is to move the Text out of centerRect, so it will not be its child obj, so not influced by the side effect of DropShadow.
eg:
move the text outside and modify its conditioning like below:
Text{
text: "Hello World!"
font.pixelSize: 0.07 * centerRect.height
anchors.centerIn: centerRect
}
Related
From qml Customizing SplitView example we can see handle is Rectangle with implicitWidth 4
SplitView
{
id: splitView
anchors.fill: parent
handle: Rectangle {
implicitWidth: 4
implicitHeight: 4
color: SplitHandle.pressed ? "#81e889"
: (SplitHandle.hovered ? Qt.lighter("#c2f4c6", 1.1) : "#c2f4c6")
}
Rectangle {
implicitWidth: 150
color: "#444"
}
Rectangle {
implicitWidth: 50
color: "#666"
}
}
I my pet project I set it to 2, but now it's difficult to resize SplitView because mouse hover area is too tight. I don't want to make it bigger itself, but would like to increase only mouse hover area. I gave some tries, but without success. Is it possible?
This is an unfortunate limitation that will be fixed in 6.2 thanks to a series of community contributions. The solution will then be to use a containmentMask:
https://codereview.qt-project.org/gitweb?p=qt/qtquickcontrols2.git;f=src/quickcontrols2/doc/snippets/qtquickcontrols2-splitview-handle-containmentmask.qml;hb=refs/changes/18/359318/1#l40
SplitView uses the root handle item to determine the touchable area, but if you try to use a plain Item to increase that area, it will affect the visual size of the handle, which is typically not desirable:
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
width: 640
height: 480
visible: true
SplitView {
anchors.fill: parent
handle: Item {
implicitWidth: 32
Rectangle {
implicitWidth: 4
anchors.horizontalCenter: parent.horizontalCenter
height: parent.height
color: SplitHandle.pressed ? "#81e889"
: (SplitHandle.hovered ? Qt.lighter("#c2f4c6", 1.1) : "#c2f4c6")
}
}
Rectangle {
implicitWidth: 150
color: "#444"
}
Rectangle {
implicitWidth: 50
color: "#666"
}
}
}
Notice the large white area which shouldn't be there:
I want to set the size (mainly height) of my popup to fit the contents depending on how much text is shown or whether there's an icon image shown on popup. How do I set the height of popup.
Eg.
Popup {
id: popup
width: window.width/2
height: window.height/4
x: window.width/2 - width/2
y: window.height/2 - height/2
Rectangle {
id: popupContent
width: parent.width
height: parent.height
visible: notification
anchors.fill: parent
Rectangle {
id: iconField
anchors.top: parent.top
width: parent.width
height: parent.height/2
Image {
id: img
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
width: window.width/18
height: window.width/18
fillMode: Image.PreserveAspectFit
source: "qrc:/images/icons/info.png"
}
}
Rectangle {
id: textField
anchors.top: iconField.bottom
width: parent.width
height: parent.height/2
Text {
id: text1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignHCenter
width: parent.width
wrapMode: Text.WordWrap
text: "This long text overflows out of the popup up rectangle!"
}
}
}
}
If I use a long text then the text overflows from the popup rectangle. I tried using implicitHeight in different places but I don't understand how to apply it in this situation.
There's several issues with your code. It's hard to make a perfect answer because I don't know exactly what's intended. For example, your text will always be off the bottom of the Rectangle because you anchored textField's anchor.top to iconField.bottom, and iconField is the same size as the entire popup. But here's some ideas on how to improve it.
Your popupContent is a Rectangle, but I'm not sure if you actually are intending to draw a rectangle there or not. I think you could replace that with a ColumnLayout like the example here.
You can also manually specify the height of your content using the contentHeight property. You could set it to the height of your iconField plus the height of your textField, plus any padding you want.
Every Item has a property called childrenRect.height which will tell you the combined height of all of its children.
For all of these options though, you will need to stop setting every object's height to be the same as its parent's height.
The problem is in position and width of the horizontal scrollbar and position of the content that has been scrolled when I resize the width of the window (parent) element in RTL direction.
When I do these steps:
Resize the width of window in LTR direction.
Everything is working fine.
Change scrollbar position to any other position that is different from 0.0, (for example move it all the way to the right side)
Resize the width of window in opposite (RTL) direction
Scrollbar starts to behave odd and scrollable content is in the wrong position
I get this situation:
Width of scrollbar's contentItem (aka scrollbar's handle) is wrongly calculated.
Scrollbar's position is also wrongly calculated
The content is not scrolled to the right place (property "x" of scrollable content is wrongly calculated )
What I want is that:
the width of scrollbar's contentItem (aka scrollbar's handle) increases proportionately as the width of the window increases
the content (which was in the position that its right side was completely visible) should stay in that position. And with the expansion of the window, on the left side, the other part of the content that was not visible until then, should start to show up.
The same things are happening if I try to use non-attached QML ScrollIndicator.
This seams to be the bug in QML, and I have reported it, but I need the solution now... If anyone could help, it would be great. Thanks!
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
Window
{
id: main
width: 400
height: 200
Rectangle
{
id: frame
clip: true
anchors.fill: parent
color: "purple"
Text
{
id: content
text: "ABCDE"
font.pixelSize: 160
x: -hbar.position * width
}
ScrollBar
{
id: hbar
hoverEnabled: true
active: true
policy: ScrollBar.AlwaysOn
visible: size < 1
orientation: Qt.Horizontal
size: frame.width / content.width
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
background: Rectangle
{
color: "black"
}
}
}
}
scrollbar behavior
You should consider using a Flickable instead of setting the position of your text manually:
Flickable {
anchors.fill: parent
contentWidth: content.paintedWidth
boundsBehavior: Flickable.StopAtBounds
ScrollBar.horizontal: ScrollBar {
hoverEnabled: true
active: true
policy: ScrollBar.AlwaysOn
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
background: Rectangle {
color: "black"
}
}
Rectangle {
id: frame
clip: true
anchors.fill: parent
color: "purple"
Text {
id: content
text: "ABCDE"
font.pixelSize: 160
}
}
}
Edit:
If you really need the ScrollBar to be attached to a Rectangle, you can add bounds to your Text position:
x: Math.min(0, Math.max(-hbar.position * width, frame.width - content.width))
with
ScrollBar {
visible: frame.width < content.width
// ...
}
I'm new of qml.
I'm starting to develop a little application with a custom item.
when I try to use in application anchor.top: first_item.bottom, to position the rectangles of the custom component, one below the other doesn't work.
content file main.qml:
import QtQuick 2.5
Item
{
id:main_screen
Rectangle
{
width: 300
height: 60
id: text_content
color: "DarkGray"
opacity: 0.9
border.color: "blue"
border.width: 3
radius: 5
z:6
Text {
id: titleText
width: parent.width
height: parent.height
font.pointSize: 20
font.family: "Arial"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: "Test - title"
color: "White"; style: Text.Raised;
}
}
//..................This rectangle is shown below main_screen... so is OK
Custom_item
{
id:first_item
anchors.top: main_screen.bottom
}
//..................This rectangle is not shown below first_item... but it shown on absolute top, in overlap of retangle title
Custom_item
{
id:second_item
anchors.top: first_item.bottom
}
//..................This rectangle is not shown below second_item... but it shown on absolute top, in overlap of retangle title
Custom_item
{
id:third_item
anchors.top: second_item.bottom
}
}
content file Custom_item.qml
import QtQuick 2.5
Item
{
id:testComponent
Rectangle
{
width: 300
height: 60
id: text_content
color: "DarkGray"
opacity: 0.9
border.color: "blue"
border.width: 3
radius: 5
z:6
}
}
what am I doing wrong ?
Thanks
The problem lies within the dimensions of the objects your are anchoring to.
Though the Rectangles have a width and a height, the enclosing Item has none, so it is basically 0 pixels in height and width, while the Rectangle protrudes it.
If you don't have any reason for enclosing the Rectangle within the Item, I'd reccomend you, to take the Rectangle itself as the toplevel element of the file.
Reasons for having the Item might be those:
Hiding the Rectangles properties
Having multiple children for the Item that are logically siblings to the Rectangle
... other reasons might exist ;-)
Nevertheless, you need to make sure, that the toplevel item has always the right dimensions. So you should set the width and height, better the implicitWidth and implicitHeight in component declarations.
Example 1: Without an Item
import QtQuick 2.5
Rectangle {
id: root
width: 300
height: 60
color: "DarkGray"
opacity: 0.9
border.color: "blue"
border.width: 3
radius: 5
z:6
}
Example 2: With Item
import QtQuick 2.5
Item {
id:testComponent
implicitHeight: 60 // < This
implicitWidth: 300 // < and that are important to have the dimensions
Rectangle {
id: text_content
anchors.fill: parent
color: "DarkGray"
opacity: 0.9
border.color: "blue"
border.width: 3
radius: 5
z:6
}
}
You are anchoring all the Rectangle's to the Item hence you are not getting the desired result. Simple change the id of the top Rectangle as follows
Item
{
id: root
Rectangle
{
id:main_screen
...
}
}
How can i draw a drop shadow for a Rectangle visual item on QtQuick 2.0?
I like to draw a drop shadow for my main window (I have a transparent and no-decorated window)
As a workaround for the clipped shadow issue, you can put your Rectangle in an Item, with additionnal margin to take blur radius in account, and apply shadow on that container:
import QtQuick 2.0
import QtGraphicalEffects 1.0
Item {
width: 320
height: 240
Item {
id: container
anchors.centerIn: parent
width: rect.width + (2 * rectShadow.radius)
height: rect.height + (2 * rectShadow.radius)
visible: false
Rectangle {
id: rect
width: 100
height: 50
color: "orange"
radius: 7
antialiasing: true
border {
width: 2
color: "red"
}
anchors.centerIn: parent
}
}
DropShadow {
id: rectShadow
anchors.fill: source
cached: true
horizontalOffset: 3
verticalOffset: 3
radius: 8.0
samples: 16
color: "#80000000"
smooth: true
source: container
}
}
Just use DropShadow from the QtGraphicalEffects module.
A complete, working example:
import QtQuick 2.0
import QtGraphicalEffects 1.0
Rectangle {
width: 640
height: 480
color: "blue"
Rectangle {
id: rect
anchors.centerIn: parent
width: 100
height: 100
color: "red"
}
DropShadow {
anchors.fill: rect
cached: true
horizontalOffset: 3
verticalOffset: 3
radius: 8.0
samples: 16
color: "#80000000"
source: rect
}
}
Note that you will see a number of warnings like this:
file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/DropShadow.qml:391:5:
QML SourceProxy: Binding loop detected for property "output"
file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/private/GaussianDirectionalBlur.qml:66:5:
QML SourceProxy: Binding loop detected for property "output"
file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/private/GaussianDirectionalBlur.qml:61:5:
QML SourceProxy: Binding loop detected for property "output"
file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/private/GaussianDirectionalBlur.qml:66:5:
QML SourceProxy: Binding loop detected for property "output"
file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/private/GaussianDirectionalBlur.qml:61:5:
QML SourceProxy: Binding loop detected for property "output"
file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/private/GaussianGlow.qml:53:5: QML SourceProxy: Binding loop detected for property "output"
Those warnings are QTBUG-28521, which has been fixed in Qt 5.0.2 (which at the time of this writing has not yet been released). Fortunately, there's no actual problem, aside from the annoying console output.
Interesting question... I've been searching for a better way to do this. This is my quick and dirty way of accomplishing a drop shadow effect for a QML Rectangle for the time being.
Rectangle{
width: 500
height: 500
color: "dark grey"
Rectangle {
id: backgroundRect
width: 200
height: 150
radius: 5
anchors.centerIn: parent
color: "red"
Rectangle {
id: dropShadowRect
property real offset: Math.min(parent.width*0.025, parent.height*0.025)
color: "purple"
width: parent.width
height: parent.height
z: -1
opacity: 0.75
radius: backgroundRect.radius + 2
anchors.left: parent.left
anchors.leftMargin: -offset
anchors.top: parent.top
anchors.topMargin: offset
}
}
}
I tried the code above and it in fact adds a shadow, although in my case simply adding another rectangle with a bit on an offset gave me an effect that I liked more.
Rectangle{
id: rec_Shadow
height:rect_withShadow.height
width: rect_withShadow.width
border.color: "#B3B3B3"
color: "#C5C5C5"
anchors{
verticalCenter: rect_withShadow.verticalCenter
horizontalCenter: rect_withShadow.horizontalCenter
horizontalCenterOffset: 5
verticalCenterOffset: 5
}
radius: rect_withShadow.radius
}
Next you add the Rectangle on which you want the shadow, and you call it rect_withShadow