I've created a new project and added a scrollview with a rectangle. When I start the project the rectangle is not displayed but if I add an other control it appears. I'm not sure what I'm doing wrong, I want to see the rectangle always.
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
id: mainWindow
ScrollView{
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.topMargin: 0
anchors.bottomMargin: 0
width: 289
Rectangle{
anchors.fill: parent
color: "blue"
MouseArea
{
anchors.fill: parent
onClicked: console.log("Click")
}
}
}
}
With this code I get the following window (rectangle is not visible):
However if I add a button to this ScrollView...
ScrollView{
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.topMargin: 0
anchors.bottomMargin: 0
width: 289
Rectangle{
anchors.fill: parent
color: "blue"
MouseArea
{
anchors.fill: parent
onClicked: console.log("Click")
}
}
Button{
text:"Test"
}
}
The rectangle appears:
What's wrong with my first code (without the button)?
The ScrollView has two sizes, the size of the control view in the UI, and the size of the content of the ScrollView.
When you add the Rectangle without the Button, you instruct the Rectangle to fill its parent. The parent in this case is the content of the ScrollView. By default that content is empty, and you've instructed the Rectangle to fill this empty space. Therefore there is nothing displayed.
When you add the Button which has an explicit size, it forces the content of the ScrollView to be non-empty, so now the Rectangle has something to fill, thus you see it.
Related
I tried to create a child window to show an article that can't be fully displayed by the window. For now, I can slide the page through dragging the ScrollBar (QML Type), but I want to slide it by using the mouse wheel as well.
Here is the code:
import QtQuick 2.2
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
id:privacyWindow
width: 640
height: 480
title:qsTr("Privacy")
Rectangle {
id: privacy
clip: true
width: privacyWindow.width
height: privacyWindow.height
anchors.centerIn: parent
Rectangle {
id: textArea
clip: true
width: privacyWindow.width - 150
height: privacyWindow.height
anchors.centerIn: parent
Text {
id: content
width: textArea.width
text: ""
wrapMode: Text.WordWrap
textFormat: Text.RichText
//x: -horizontalBar.position * width
y: -verticalBar.position * height
}
}
ScrollBar {
id: verticalBar
hoverEnabled: true
active: hovered || pressed
orientation: Qt.Vertical
size: privacy.height / content.height
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: parent.bottom
}
}
}
Any help would be greatly appreciated! Thank you. :)
I have managed to solve it by replacing Rectangle with Flickable.
import QtQuick.Controls 2.12
Window {
id: privacyWindow
width: 640
height: 480
title:qsTr("Privacy")
Flickable {
id: flickable
clip: true
width: privacyWindow.width - 150
height: privacyWindow.height
contentWidth: content.width
contentHeight:content.height
anchors.centerIn: parent
Text {
id: content
width: flickable.width
text: ""
wrapMode: Text.WordWrap
textFormat: Text.RichText
}
ScrollBar.vertical: ScrollBar {
parent: flickable.parent
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: parent.bottom
}
}
}
I have the following QML layout of the main application window. I need to create shadow for borderless window, that's why inner rectangle is a bit smaller than the application border (I found this solution on the StackOverflow before). The problem is when a new item is pushed to the nested StackView, it moves from the outside of the inner rectangle. How should I fix it?
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.2
import QtGraphicalEffects 1.0
import org.b2soft.qml 1.0
ApplicationWindow {
id: window
visible: true
width: 800
height: 600
title: qsTr("Test")
color: "#00000000"
flags: Qt.FramelessWindowHint | Qt.Window
Rectangle {
id: rect
width: 700
height: 500
anchors.centerIn: parent
Column {
id: column
anchors.fill: parent
Row {
id: topbar
anchors.left: parent.left
anchors.right: parent.right
height: 24
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: parent.width
color: "#37373a"
}
}
StackView {
id: rootStackView
anchors.left: parent.left
anchors.right: parent.right
height: parent.height - topbar.height
initialItem: Qt.resolvedUrl("login.qml")
}
Connections {
target: QMLWrapper
onLoginCompleted: rootStackView.push(Qt.resolvedUrl("main_stack.qml"))
}
}
}
DropShadow {
anchors.fill: rect
radius: 40
samples: 32
verticalOffset: 14
source: rect
color: "#40000000"
}
}
Below is the GIF with the issue:
I'd go on a limb and assume that's the default intended behavior. QML elements do not clip by default, out of concern it might be a heavy operation.
And the stack view is usually contained inside the application window, so this issue would not be prominent.
But yours is nested into a smaller element, leaving room for the artifact to manifest.
All you have to do is set clip: true for rect.
I have a simple component which is designed to show an image with some text under it as follows:
Rectangle{
id: functionView
RowLayout {
spacing: 350
anchors.centerIn: parent
Item {
Image {
id: upload_pic
source: "http://icons.iconarchive.com/icons/custom-icon-design/mono-general-4/128/upload-icon.png"
Text {
text: "Upload Images"
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottomMargin: -20
}
}
Layout.fillWidth: true
}
Item {
Image {
id: workflow_pic
source: "http://icons.iconarchive.com/icons/icons8/windows-8/128/Data-Workflow-icon.png"
Text {
text: "Upload Workflow"
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottomMargin: -20
}
}
Layout.fillWidth: true
}
}
}
However, this is not aligned (either vertically or horizontally) on the component window. This can be verified using qmlscene. The images are directly linked in the component source.
You are trying to center your RowLayout in its parent, which is a Rectangle that doesn't have its width property set.
Set the rectangle's width to some value or to its parent width for example by width: parent.width or by setting its anchors like for example:
anchors.left: parent.left
anchors.right: parent.right
like the web pages,when content's high beyond the rectangle,there is a scrollbar.
Is there anyone else who can help me?
I have tried with listview,but I can't use it in a rectangle
There is an example in the docs, how to use ScrollBar without a Flickable:
import QtQuick 2.7
import QtQuick.Controls 2.0
Rectangle {
id: frame
clip: true
width: 160
height: 160
border.color: "black"
anchors.centerIn: parent
Text {
id: content
text: "ABC"
font.pixelSize: 160
x: -hbar.position * width
y: -vbar.position * height
}
ScrollBar {
id: vbar
hoverEnabled: true
active: hovered || pressed
orientation: Qt.Vertical
size: frame.height / content.height
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: parent.bottom
}
ScrollBar {
id: hbar
hoverEnabled: true
active: hovered || pressed
orientation: Qt.Horizontal
size: frame.width / content.width
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
}
}
adding rectangle into flickable solved my problem
import QtQuick.Controls 2.5
import QtQuick.Controls.Material 2.5
import QtQuick 2.8
Item {
id: item1
visible: true
width: 800
height: 600
ScrollView {
id: frame
clip: true
anchors.fill: parent
//other properties
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
Flickable {
contentHeight: 2000
width: parent.width
Rectangle {
id : rectangle
color: "#a7c4c6"
radius: 6
//visible: !busyIndicator.running
anchors.fill: parent
}
}
}
}
I'm using Qt 5.2.1 for windows (Qt creator 3.0.1)
I have a custom QML component, it works fine when I'm loading in into rectangle:
import QtQuick 2.0
import QtQuick.Controls 1.1
Rectangle {
id: mainRectangle
anchors.fill: parent
Loader {
anchors.top: parent.top;
anchors.left: parent.left;
anchors.right: parent.right;
id: ld01;
onLoaded: {
ld01.visible = true;
anchors.top = parent.top;
}
}
Loader {
anchors.top: ld01.bottom;
anchors.left: parent.left;
anchors.right: parent.right;
id: ld02;
onLoaded: {
anchors.top = ld01.bottom;
ld02.visible = true;
}
}
Component.onCompleted: {
ld01.setSource("View_item2.qml");
ld02.setSource("View_item2.qml");
}
}
But when I'm trying to put it all inside a ScrollView, elements of my component are moved somewhere. What kind of trick I should implement for correct use of ScrollView?
ScrollView {
id: mainTabLayout
anchors.fill: parent
anchors.margins: 4
//here I put a code from above (except imports, of course)
}
Component code is below:
import QtQuick 2.1
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.0
Rectangle {
id: slv_layout
objectName: "itemColumnLayout"
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 1
property int minimal_height: 200
height: 400
color: "green"
MouseArea {
property bool is_pressed: false
property int initial_y: 0
property int proposed_y: 0
id: resizeStick
enabled: true
anchors.bottom: parent.bottom
height: 10
width: parent.width
hoverEnabled: true
onEntered: {
cursorShape = Qt.SizeVerCursor;
}
onPressed: {
is_pressed = true;
initial_y = mouseY;
}
onReleased: {
is_pressed = false;
}
onMouseYChanged: {
if (is_pressed) {
proposed_y = slv_layout.height + mouseY - initial_y;
if (proposed_y >= slv_layout.minimal_height) {
slv_layout.height += (mouseY - initial_y);
initial_y = mouseY;
}
}
}
}
Text {
id: slvTitle
text: "device name"
anchors.top: parent.top
anchors.left: parent.left
anchors.margins: 2
}
Rectangle {
anchors.top: slvTitle.bottom
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.topMargin: 2
color: "blue"
Button {
id: slv_butt_run;
objectName: "slv_butt_run"
width: 60
height: width
text: "Run"
anchors.top: parent.top
anchors.left: parent.left
anchors.margins: 2
}
Button {
id: slv_butt_settings;
objectName: "slv_butt_settings"
width: 60
height: width
text: "Settings"
anchors.top: parent.top
anchors.left: slv_butt_run.right
anchors.margins: 2
}
Button {
id: slv_butt_stop;
objectName: "slv_butt_stop"
width: 60
height: width
text: "Stop"
anchors.top: slv_butt_run.bottom
anchors.left: parent.left
anchors.margins: 2
}
Button {
id: slv_butt_expand;
objectName: "slv_butt_expand"
width: 60
height: width
text: "Expand"
anchors.top: slv_butt_settings.bottom
anchors.left: slv_butt_stop.right
anchors.margins: 2
}
TextArea {
id: slv_log_area
anchors.left: slv_butt_expand.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.margins: 3
}
}
}
How it looks when all is ok:
How it looks when not ok:
Actually, I still don't know, why code works as described above. But I have found acceptable method to solve task other way.
Looks like "put a needle into egg, egg into duck, duck into rabbit":
ScrollView must contain a ListView component which has a corresponding ListModel and a custom component should act as delegate. Only with ListModel I've got correct automatic scrolling and relative emplacement support.
ScrollView {
id: id_scrollView
anchors.fill: parent
objectName: "ScrollView"
frameVisible: true
highlightOnFocus: true
style: ScrollViewStyle {
transientScrollBars: true
handle: Item {
implicitWidth: 14
implicitHeight: 26
Rectangle {
color: "#424246"
anchors.fill: parent
anchors.topMargin: 6
anchors.leftMargin: 4
anchors.rightMargin: 4
anchors.bottomMargin: 6
}
}
scrollBarBackground: Item {
implicitWidth: 14
implicitHeight: 26
}
}
ListView {
id: id_listView
objectName: "ListView"
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 11
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
delegate: view_component
model: id_listModel
ListModel {
id :id_listModel
objectName: "ListModel"
}
//delegate: View_item2.Item
Component {
id: view_component
View_item2 {
objectName: name
}
}
}
According to the ScrollView documentation,
A ScrollView can be used either to replace a Flickable or decorate an existing Flickable. ... The width and height of the child item will be used to define the size of the content area.
A ScrollView needs to know two width-height pairs: the first one is the width and height used to display the region, and the second one is the width and height of the content. If the area of the content is larger than the display area, the display area will add a scroll bar on it.
In your example:
ScrollView {
id: mainTabLayout
anchors.fill: parent
//other properties
Rectangle {
id: mainRectangle
anchors.fill: parent
//...
}
}
The width and height of the content is bound to the display area, making the two areas be in the same size. The width and height of display area is the one in mainTabLayout, which is bound to it's parent; and the width and height of the content is the one in mainRectangle, which is bound to it's parent, mainTabLayout. Therefore the ScrollView cannot work correctly since ScrollView expects the two values are different, not bound together.
To solve your problem, you can explicitly assign width and height to mainRectangle. Do not bind the width and height of mainRectangle to it's parent using anchors.fill:parent.
ScrollView {
id: mainTabLayout
anchors.fill: parent
//other properties
Rectangle {
id: mainRectangle
width: 800; height: 800 //not binding to parent.width & height
//...
}
}
And this can work correctly.