I designed my main interface with two levels of splitview in order to get five rectangle areas.
Here is my code :
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls 1.4
import "../geoforms"
SplitView {
id: splitView0
orientation: Qt.Horizontal
// anchors.fill: parent
SplitView {
id: splitView1
width: window.width/10*8
height: 900
Layout.minimumWidth: window.width/10*2
Layout.maximumWidth: window.width/10*8
orientation: Qt.Vertical
MapRectangle{
id:newMapRectangle
height: 300
width: 700
anchors.top: parent.top
anchors.left:parent.left
anchors.right: parent.right
Layout.fillHeight: true
}
FPArea{
id: flightPlanArea
}
}
SplitView {
id: splitView2
width: 100
height: 100
orientation: Qt.Vertical
FPMap{
id: newFlightPlanMap
}
AltitudePM{
id: newAltitudePlanMap
}
IME{
id: newButtonArea
color: "grey"
mainGridProp.rows : 3
mainGridProp.columns: 2
mainGridProp.spacing: 20
}
} //Splitview2
} //Splitview
I need to manage a stackview for the splitview1.MapRectangle area. For that, I added a stackview in the code, like this :
import QtQuick 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 1.4
Item{
id: itemMapRectangle
Rectangle {
id: mapRect
color: "#4c4e50"
border.color: "#404244"
border.width: 3
}
StackView{
id: stackView
anchors.fill: parent
focus: true
initialItem: Item {
id: page
}
}
}
The result is weird.
Furthermore, documentation says : "Using StackView in an application is typically a simple matter of adding the StackView as a child of a Window.". So I'm afraid stackview to be only bindable to a window.
Is there a way to link it to part of a window via a splitview ? If yes, is it possible to have multiple stackview for different areas of the interface ?
SplitView is a regular control as all other QML controls so you can set size/anchors as you want. But SplitView implements attached properties of Layout so you should use its properties to set size of inner elements. For example:
SplitView {
anchors.fill: parent
orientation: Qt.Horizontal
StackView {
Layout.fillHeight: true
Layout.minimumWidth: 200
initialItem: Rectangle {
color: "orange"
}
}
StackView {
Layout.fillHeight: true
Layout.fillWidth: true
initialItem: Rectangle {
color: "yellow"
}
}
}
Related
I have a QML code like this:
MyItem.qml:
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
Item {
id: root
width: parent.width
height: grid.height
Rectangle {
anchors.fill: root
color: "blue"
z: -1
}
Flow {
id: grid
width: parent.width
spacing: 5
Button {
text: qsTr("Button 1")
}
Button {
text: qsTr("Button 2")
}
Button {
text: qsTr("Button 3")
}
}
}
main.qml:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout {
anchors.fill: parent
Button {
Layout.fillWidth: true
Layout.fillHeight: true
text: "hello"
}
MyItem {
Layout.fillWidth: true
}
}
}
If the Flow is wide enough for all three buttons to be at the same line (as with RowLayout) there is an extra empty space at the bottom of the Flow (approximately Button.height * 2). Looks like the Flow height is always calculated as the sum of all its element heights.
What is the logic behind this behavior? How to make the Flow fit its content height?
EDIT1: It is not Flow, but 'root' item has the wrong height.
EDIT2: Download the sample app
The problem with your code is that the root element the expressions:
anchors.fill: parent
height: grid.height
are competing, in the first expression you indicate that the dimensions of the root will take the size of the window and this implies the height but in the next expression you are indicating that the height will no longer be from the window but from the grid, so that generates an indefinite behavior. The only solution is to establish that the width of the root item is that of the window.
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Item {
id: root
height: grid.height
width: parent.width
Rectangle {
anchors.fill: root
color: "blue"
}
Flow {
id: grid
width: parent.width
spacing: 5
Button {
text: qsTr("Button 1")
}
Button {
text: qsTr("Button 2")
}
Button {
text: qsTr("Button 3")
}
}
}
}
Update:
It seems that you do not know how they work (read https://doc.qt.io/qt-5/qml-qtquick-layouts-layout.html#details), by default the height that is taken is the implicitHeight.
Also if you use layout you should not set anchors in the items that are directly affected by the layouts, in your case the CommandsTab is affected by the Layout so you should not use width: parent.width, is unnecesary.
CommandsTab.qml
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
Item {
id: root
implicitHeight: grid.height
Rectangle {
anchors.fill: root
color: "blue"
z: -1
}
Flow {
id: grid
width: parent.width
spacing: 5
Button {
text: qsTr("Button 1")
}
Button {
text: qsTr("Button 2")
}
Button {
text: qsTr("Button 3")
}
}
}
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout {
anchors.fill: parent
Button {
Layout.fillWidth: true
Layout.fillHeight: true
text: "hello"
}
CommandsTab {
Layout.fillWidth: true
}
}
}
I have the list view. When I scroll items the top element can stop any position and can be seen half height. enter image description here
But I need that after scrolling stop the top element can be seen full height.enter image description here
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.12
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Scroll")
ColumnLayout {
anchors.fill: parent
RowLayout {
id: buttonsRow
Button {
text: "Open dump file"
}
Button {
text: "Copy raw data to clipboard"
}
}
ListView {
id: listView
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
model: 100
clip: true
delegate: ItemDelegate {
text: modelData
Rectangle
{
width: parent.width - 5
height: parent.height - 5
color: "green"
}
}
Layout.fillWidth: true
Layout.fillHeight: true
ScrollBar.vertical: ScrollBar {}
}
}
}
Use the snapMode property:
ListView {
snapMode: ListView.SnapToItem
// ...
}
When I execute my QML code, the output is:
When I minimize the window, It becomes like
and finally, when I again maximize the window it changes to
the GUI which I want to make looks like
![][5]
I am not getting what is the issue for all of the changes in GUI at different events. And this is the Qml code which I wrote
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
Window {
visible: true
width: 1080
height: 720
title: qsTr("Login")
GridLayout{
Rectangle{
id:one
Rectangle
{ id:two
color:"black";
width: 700
height:40
}
Image {
id: image
x: 470
y: 0
width: 54
height: 42
source: "qrc:/user.png"
}
Rectangle
{
id:three;
color:"#f47a42";
width: 200
height:40
anchors.left:two.right;
anchors.margins:940
Text {
id: user
text: qsTr("4200")
color:"white"
anchors.top: value.bottom
}
Text
{
id: value;
text: qsTr("User");
color:"yellow"
}}
}
}
Rectangle{
ColumnLayout{
width: 50
height: childrenRect.height+fillHeight;
}
color:"green"
}
}
So why this is happening and how can I solve this problem?
Output of the code below
Here is example of scalable window:
import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Layouts 1.11
Window {
visible: true
width: 800
height: 600
title: qsTr("Layout example")
ColumnLayout{
spacing: 0
anchors.fill: parent
Item {
id: titlebar
Layout.preferredHeight: 40
Layout.fillWidth: true
RowLayout {
anchors.fill: parent
spacing: 0
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: "orange"
Text {
anchors.centerIn: parent
text: "Title"
}
}
Rectangle {
Layout.preferredWidth: 100
Layout.fillHeight: true
color: "lightgreen"
Text {
anchors.centerIn: parent
text: "Actions"
}
}
}
}
Rectangle {
id: content
Layout.fillHeight: true
Layout.fillWidth: true
color: "lightyellow"
Text {
anchors.centerIn: parent
text: "Content"
}
}
}
}
I'm trying to get a tool bar working but the first 3 tab buttons keep writing on top of each other.
Each tab gets display on top of one another on the left hand side of the screen.
I would like each tab button to fill and take up its on unique space.
How do I get the toolbar to display 3 individual tabs that span horizontally across the screen at equal size?
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls.Material 2.1
import QtGraphicalEffects 1.0
import "../controls" as Controls
Page{
anchors.fill: parent
header: ToolBar{
Material.background: "green"
TabButton {
id: tab1
width: parent.width/3
text: qsTr("Asset")
Image{
source: "../assets/clipboard.png"
}
onClicked: qmlfile1 = "./asset.qml"
}
TabButton {
id:tab2
width: parent.width/3
text: qsTr("Issue")
Image{
source: "../assets/wrench.png"
}
onClicked: qmlfile1 = "./issue.qml"
}
TabButton {
width: parent.width/3
id: tab3
text: qsTr("Log")
Image{
source: "../assets/cogs.png"
}
onClicked: qmlfile1 = "./log.qml"
}
}
Rectangle{
id: loader1
Loader{
width: pageApp.width
source: qmlfile1
}
Component.onCompleted: {
console.log(loader1.height)
console.log(pageApp.height)
console.log(tabBarApp.height)
}
}
}
The solution was to add row layout and each tab button gets
Layout.fillHeight: true
Layout.fillWidth: true
which fills the tabs out to occupy all space it needs
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls.Material 2.1
import QtGraphicalEffects 1.0
import "../controls" as Controls
Page{
anchors.fill: parent
header: ToolBar{
Material.background: "green"
RowLayout {
anchors.fill: parent
TabButton {
id: tab1
width: parent.width/3
text: qsTr("Asset")
Layout.fillHeight: true
Layout.fillWidth: true
Image{
source: "../assets/clipboard.png"
Layout.alignment: Qt.AlignLeft
}
onClicked: qmlfile1 = "./asset.qml"
}
TabButton {
id:tab2
width: parent.width/3
Layout.fillHeight: true
Layout.fillWidth: true
text: qsTr("Issue")
Image{
source: "../assets/wrench.png"
Layout.alignment: Qt.AlignLeft
}
onClicked: qmlfile1 = "./issue.qml"
}
TabButton {
width: parent.width/3
Layout.fillHeight: true
Layout.fillWidth: true
id: tab3
text: qsTr("Log")
Image{
source: "../assets/cogs.png"
Layout.alignment: Qt.AlignLeft
}
onClicked: qmlfile1 = "./log.qml"
}
}
}
// Add a Loader to load different samples.
// The sample Qml files can be found in the Samples folder
Rectangle{
id: loader1
Loader{
width: pageApp.width
source: qmlfile1
}
Component.onCompleted: {
console.log(loader1.height)
console.log(pageApp.height)
console.log(tabBarApp.height)
}
}
}
My program consisted of a tabbar and stackLayout. I face a layout problem that the tab button is too close to the head of the listview as shown below. They are horizontally aligned together.
But I want the listview to be under the tab button. I tried adding the topMargin in the listview, but it doesn't have any effect at all. Please help.
The code:
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtMultimedia 5.8
import QtQuick.Layouts 1.3
import com.contentplayermod.filemodel 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Tabs")
property int idx: 0
property bool isActive: true
TabBar {
id: bar
width: parent.width
TabButton {
text: qsTr("Main")
}
TabButton {
text: qsTr("View")
}
}
StackLayout {
id: stackLayout
height:parent.height
width: parent.width
currentIndex: bar.currentIndex
Item {
id: mainTab
anchors {
topMargin:60
}
width: 500
height:800
ListView {
id: lv
anchors.margins: 50
width: 200; height: 400
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
focus: true
currentIndex: 0
Component {
id: fileDelegate
Text {
text: fileName
font.pointSize: 20
anchors {
topMargin:60
}
MouseArea{
anchors.fill: parent
}
}
}
model: FileModel{
id: myModel
folder: "c:\\folder"
nameFilters: ["*.mp4","*.jpg"]
}
delegate: fileDelegate
highlightFollowsCurrentItem: true
}
}
Item {
id: viewTab
width: 500
height:800
}
}
}
You can either anchors your stack-top to the bottom of the tab bar like this :
...
StackLayout {
id: stackLayout
height:parent.height - bar.height
anchors.top: bar.bottom
width: parent.width
...
Or much simpler, put everything in a ColumnLayout :
ColumnLayout {
anchors.fill: parent
TabBar {
id: bar
Layout.fillWidth: true
...
}
StackLayout {
id: stackLayout
Layout.fillHeight: true
Layout.fillWidth: true
...
}
}
So you don't have to deal with width and height, and it's more easy to insert new widgets in your window.
You can add spacing to the ColumnLayout to put some space between the TabBar and the content. Or manage this inside the Items displayed by the StackLayout for more flexibility.