This code does produce checkboxes in a tableview but when I click on the checkbox it becomes big. I want it to remain of a constant size.
Please guide.
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.1
Rectangle
{
id: rightside
anchors.fill: parent
height: parent.height
width: 1500
TableView
{
anchors.fill: parent
TableViewColumn
{
role: "selectall"
title: "Select All"
width: 100
delegate: CheckBox
{
anchors.fill: parent
checked: false
}
}
TableViewColumn {
role: "size"
title: "Size"
width: 100
}
TableViewColumn
{
role: "last_updated"
title: "Last Updated"
width: 100
delegate: Component
{
Rectangle
{
height: 100
width: 120
id: head
RowLayout
{
height: parent.height
width: parent.width
Rectangle
{
height: 20
width: 20
color: "red"
border.color: "black"
radius: 100
MouseArea
{
anchors.fill: parent
onClicked: parent.color = "grey"
}
}
}
}
}
}
model: ListModel
{
id: mymodel
ListElement { text: "Banana" }
ListElement { text: "Apple" }
ListElement { text: "Coconut" }
}
}
}
There are lots of way to solve your problem. But first, let's do proper distinction between Qt Qtuick Controls versions. To do it, use this import statement:
import QtQuick.Controls 1.4 as QC1
And respectively use all components that requires QC1, e.g.: QC1.TableView, QC1.TableViewColumn.
In your example you are getting overlapping of components. To avoid it in terms of QC1 you can define a higher row delegate for your TableView. But this discards the default style. Simple example of its usage with style goes here:
rowDelegate: Rectangle {
height: 30
SystemPalette {
id: myPalette
colorGroup: SystemPalette.Active
}
color: {
var baseColor = styleData.alternate ? myPalette.alternateBase : myPalette.base
return styleData.selected ? myPalette.highlight : baseColor
}
}
As result you'll get this:
Another option in terms of QC2 is to redefine indicator style of CheckBox. Below you'll find an example that could possibly fit your app, based on Customizing CheckBox documentation; so your CheckBox delegate will look like this:
delegate: CheckBox {
id: control
anchors.fill: parent
checked: false
indicator: Rectangle {
id: outer
readonly property int size: 18
implicitWidth: size
implicitHeight: size
x: control.leftPadding
y: parent.height / 2 - height / 2
radius: 4
border.color: control.down ? "orangered" : "orange"
Rectangle {
id: inner
anchors.centerIn: parent
width: outer.size/2
height: width
radius: 3
color: control.down ? "orangered" : "orange"
visible: control.checked
}
}
}
As result you'll get this:
Related
The following code results in this:
I don't know where from the blue colour is coming up on selection. How do I set the background colour of a selected row in TreeView?
import QtQuick 2.2
import QtQuick.Controls 1.5
import QtQuick.Controls.Styles 1.4
import QtQml.Models 2.2
import filesystem_browser 1.0
ApplicationWindow
{
visible: true
width: 740
height: 740
Rectangle
{
anchors.centerIn: parent
color: "#292A38"
border.color: "#373848"
height: 600; width: 600
ItemSelectionModel
{
// This model is comming from C++' class DisplayFileSystemModel.
model: treeViewModel
}
TreeView
{
id: view
anchors.fill: parent
anchors.margins: 2 * 12
model: treeViewModel
rootIndex: root
selection:
ItemSelectionModel
{
model: treeViewModel
onSelectionChanged:
{
console.log( treeViewModel.data( view.currentIndex ))
}
}
style:
TreeViewStyle
{
backgroundColor: "#14161C"
highlightedTextColor: "red"
alternateBackgroundColor: "#14161C"
}
TableViewColumn
{
title: "Name"
role: "display"
resizable: true
}
itemDelegate:
Rectangle
{
color: "transparent"
height: 20
Rectangle
{
height: 20; width: 40; color: styleData.depth ? "green":"transparent";
anchors.right: parent.right
border.width: 1
}
Text
{
color: styleData.depth ? "green":"black";
anchors.verticalCenter: parent.verticalCenter
text: styleData.value
}
}
}
}
}
Add a rowDelegate to the TreeView to specify how to draw the row:
TreeView {
// ...
rowDelegate: Rectangle {
color: styleData.selected ? "red" : "transparent"
}
}
I have below stack of components and I want to read and set value of the TextFiled:
-Rectangle
-----TabView
---------Tab
-----------Rectangle
--------------GridLayout
------------------Rectangle
--------------------TextField <--- I want to access this TextField
I have also a case where I need to access Repeater inside the Tab:
-Rectangle
-----TabView
---------Tab
-----------Rectangle
--------------GridLayout
------------------Repeater
--------------------TextField <--- I want to access this TextField also
I have tried to access it using:
var tab0 = myTabView.getTab(0);
tab0.children[0].text = "Some Text"; // I get Undefined Error
I have tried to access the component using a function inside the Tab:
import QtQuick 2.0
import QtQuick.Controls 2.14 as QQC2
import QtQuick.Layouts 1.14
import QtQuick.Controls 1.4 as QQC1
QQC2.Item {
QQC1.TabView {
QQC1.Tab {
title: "tab1"
function printValue () {
console.log("myTextFld.txt: "+myTextFld.txt); // <-- Getting Error myTextFld undefined.
}
Rectangle {
id: tabHolderRext
color: "blue"
GridLayout {
id: myGrid
model: 7
Repeater {
id: herderRepeater
model: header
delegate: Rectangle {
TextField {
// I want to Access This TextField also
}
}
}
Rectangle {
id: row0Rect
Layout.row: 0
Layout.column: index
TextFiled {
id: myTextFld
text: modelData
}
}
// Rest of the rows
}
}
}
}
}
Item id can be used to access the values from TextField if you have all items in same qml file. If you have different qml files then make use of alias types link to access the values.
Repeater case: The Textfield has to update the underlying modelview --> model first then we can make use of the model's data.
Here is a sample code. I have stacked all item's in the same qml file so that access by id works here.
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
Item {
anchors.fill: parent
anchors.margins: 10
TabView {
anchors.fill: parent
Tab {
title: "TextField"
Item {
anchors.fill: parent
Grid {
spacing: 20
anchors.fill: parent
anchors.margins: 10
Rectangle {
height: 40
width: 150
TextField {
id: inputId
anchors.fill: parent
placeholderText: "enter text"
}
}
Button {
height: 40
width: 150
text: "show txt"
onClicked: labelId.text = inputId.text
}
Rectangle {
height: 40
width: 150
Label {
id: labelId
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
}
}
Tab {
title: "Repeater"
Item {
anchors.fill: parent
Grid {
spacing: 20
anchors.fill: parent
anchors.margins: 10
columns: 3
ListModel {
id: fruitModel
ListElement { name: "Apple" }
ListElement { name: "Orange" }
ListElement { name: "Banana" }
}
Repeater {
width: parent.width
height: parent.height / 2
model: fruitModel
delegate: Rectangle {
height: 40
width: 150
TextField {
anchors.fill: parent
text: name
onTextChanged: fruitModel.setProperty(index, "name", text) // update model data
}
}
}
Repeater {
width: parent.width
height: parent.height / 2
model: fruitModel
delegate: Rectangle {
height: 40
width: 150
Label {
text: name
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
}
}
}
}
}
}
I am working on some QML + c++ project and, I have a little problem with QML layouts:
I have two custom components :
First one: is a side-bar "SideTabBar.qml" (the purple rectangle in the image below).
Second one: is the element in the side-bar "SideBarElement.qml".
This image describes what I am talking about:
What I want is: highlight each side bar element on click.
To do so I am trying to iterate over the columnLayout children and lowlight them excepting the clicked one. But, I have not managed to make it works.
SideTabBar.qml:
Item {
id: sideTabBar
width: 70
height: parent.height
property string activeElement: ""
ColumnLayout{
id:sidebarLayout
anchors.fill: parent
spacing:2
SideBarElement{elementId:"a1";image:"../assets/product.svg"}
SideBarElement{elementId:"a2";image:"../assets/product.svg"}
Item {Layout.fillHeight: true}
}
}
SideBarElement.qml:
Item {
property alias image: sideBarElementicon.source
property string elementId: ""
id: sideBarElement
width:parent.width
Layout.preferredHeight: 70
Layout.alignment: Qt.AlignTop
Rectangle{
anchors.fill: parent
color:Qt.rgba(0,0,0,0)
}
Image {
id: sideBarElementicon
source: "genericIcon.png"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
width: 50
height: 50
}
MouseArea{
anchors.fill: parent
onClicked:{ sideTabBar.activeElement = elementId
// compiler does not even enter this loop.
// for(var child in Layout.children){
// console.log("this is a child")
// }
}
}
}
In this case it is better to work with a Repeater since it has an associated index and use a model to set the properties:
SideBarElement.qml
import QtQuick 2.0
Item {
property alias icon: sideBarElementicon.source
property bool highlight: false
width: parent.width
Rectangle{
anchors.fill: parent
color: highlight ? Qt.rgba(1,1,0,1) : Qt.rgba(0,0,0,0)
}
Image {
id: sideBarElementicon
source: "genericIcon.png"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
width: 50
height: 50
}
}
SideTabBar.qml
import QtQuick 2.0
import QtQuick.Layouts 1.11
Item {
id: sideTabBar
width: 70
height: parent.height
property int currentIndex: -1
ListModel{
id: elements
ListElement {
image: "../assets/product.svg"
}
ListElement {
image: "../assets/product.svg"
}
ListElement {
image: "../assets/product.svg"
}
ListElement {
image: "../assets/product.svg"
}
ListElement {
image: "../assets/product.svg"
}
ListElement {
image: "../assets/product.svg"
}
}
Rectangle{
anchors.fill: parent
color: "purple"
}
ColumnLayout{
id:sidebarLayout
anchors.fill: parent
spacing:2
Repeater{
model: elements
SideBarElement{
id: element
highlight: ix == currentIndex
icon: image
property int ix: index
Layout.preferredHeight: 70
Layout.alignment: Qt.AlignTop
MouseArea{
anchors.fill: parent
onClicked: currentIndex = ix
}
}
}
Item {Layout.fillHeight: true}
}
}
I'm working on a QML StackView that starts with a list of items to select from. Once selected I want to transition _.push(...) to a input form which has larger dimensions than the initialItem.
The only way I have trial-and-errored my way into a situation that works is by making the form Item a nested borderless window.
Q1. A nested window can't be the right type of concept to use for this... right ? there must be another way to do it. What is the right way ?
Q2. My goal after this is to have a transition animation that grows or shrinks between stacks of different sizes. Advice that doesn't preclude that would be best.
code
Main.qml :
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
ApplicationWindow {
property int itemHeight: 30
property int cornerRadius : 5
visible: true
color: "transparent"
flags: Qt.FramelessWindowHint
ListModel {
id: searchFacets
ListElement {
title: "Topics"
page: "content/TopicSearch.qml"
}
// ListElement {
// title: "Domains"
// }
}
StackView {
id: stackView
focus: true
initialItem: SearchFacets {
id: facets
}
delegate: StackViewDelegate {
pushTransition: StackViewTransition {
PropertyAnimation {
target: enterItem
property: "opacity"
from: 0
to: 1
}
}
}
}
}
Initial Item:
import QtQuick 2.3
Item {
height : listView.count * itemHeight
ListView {
id: listView
model: searchFacets
anchors.fill: parent
focus: true
highlightFollowsCurrentItem: false
highlight: Rectangle {
width: parent.width
height: itemHeight
radius : cornerRadius
color: "green"
opacity: 0.5
z:2
x: listView.currentItem.x;
y: listView.currentItem.y
Behavior on y {
SpringAnimation {
spring: 60
damping: 1.0
}
}
}
delegate: Component {
Item {
width: parent.width
height : itemHeight
Rectangle {
anchors.fill: parent
color: "#212126"
radius: cornerRadius
z:0
border.width: 2
border.color : "white"
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
console.log("clicked index: " + index)
listView.currentIndex = index
// listView.forceActiveFocus()
stackView.push(Qt.resolvedUrl(page))
}
}
Text {
text: title
font.pixelSize: 24
font.bold: true
z:1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: "white"
antialiasing: true
}
}
}
}
}
Input Form:
import QtQuick 2.3
import QtQuick.Window 2.0
Item {
Window {
width: 400
height: 400
visible: true
flags: Qt.FramelessWindowHint
Rectangle {
anchors.fill: parent
visible: true
color: "red"
}
}
}
One possible solution is to update the size of the dimensions of the StackView in the click handler that causes the transition. I do not know if that causes any problems with animating the transition.
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
console.log("clicked index: " + index)
listView.currentIndex = index
var component = Qt.createComponent(page)
var res = component.createObject(stackView)
stackView.height = res.height
stackView.width = res.width
stackView.push(res)
}
}
Here's the code:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Window 2.1
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.1
Window {
id: window
/* Interface */
Rectangle {
id: dataView
anchors.topMargin: 10
height: 30 * model.count
width: 600
radius: 5
border.color: "#333"
border.width: 1
color: "black"
opacity: 0.6
clip: true
ListView {
anchors.fill: parent
anchors.topMargin: 7
model: model
delegate: delegate
interactive: false
spacing: 6
highlight: Rectangle {
color: "#333"
border.width: 1
border.color: "red"
}
onHighlightItemChanged: {
console.debug(1);
}
}
}
/* Model */
ListModel {
id: model
ListElement {
name: "Google Chrome"
icon: ""
}
ListElement {
name: "Google Chrome"
icon: ""
}
ListElement {
name: "Google Chrome"
icon: ""
}
}
Component {
id: delegate
Rectangle {
id: wrapper
height: 24
anchors.topMargin: 7
anchors.bottomMargin: 7
Row {
anchors.fill: parent
spacing: 0
Image {
id: delegateIcon
fillMode: Image.Stretch
source: icon
width: 24
height: 24
}
Text {
text: name
font.pixelSize: 12
font.family: "Segoe UI"
color: "#fff"
}
}
}
}
}
The problem is described in the headline: when I hover an item with a mouse, nothing happens. Moreover, onHighlightItemChanged only emits at the start of the application.
What am I doing wrong?
1) You need to add a width to your delegate
id: wrapper
height: 24
becomes
id: wrapper
height: 24
width: parent.width // or 100
2) You need to trigger the action "click -> item changed", by adding this
MouseArea {
anchors.fill: parent
z: 1
onClicked:
{
list.currentIndex = index
}
}
under the delegate's Row { }
Note: onHighlightItemChanged: isn't doing what you think (it checks if the delegate component is changed, as if you have 2 possible delegates). This is better:
onCurrentIndexChanged: {
console.debug("New index : "+ currentIndex);
}