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"
}
}
Related
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:
This listview Page Code is here
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
Item {
ListModel {
id: mymodel
ListElement {
name: 'Jack'
age: 30
rank: 'Captain'
}
ListElement {
name: 'Barbossa'
age: 23
rank: 'Sailor'
}
ListElement {
name: 'Philip'
age: 19
rank: 'Sergent'
}
}
ListView {
id: list
width: parent.width
height: parent.height
anchors.centerIn: parent
spacing: 10
model: mymodel
delegate: Rectangle {
// property variant myData: model
width: parent.width
height: 20
color: 'Blue'
Text {
anchors.centerIn: parent
color: 'white'
text: 'Name: ' + name + ', Age: ' + age
font.pointSize: 20
}
MouseArea {
anchors.fill: parent
onClicked: list.currentIndex = index
}
Button {
width: 50
height: parent.height
anchors.right: parent.right
text: ">"
onClicked: {
list.currentIndex = index
mystackview.push(third_page);
}
}
}
}
}
Here is picture after running
Another code page is after clicking next arrow to get single item detail
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
Item {
Rectangle {
width: parent.width
height: 20
color: 'red'
ListView {
model: model
}
Text {
anchors.centerIn: parent
color: 'white'
text: 'Name: ' + ListModel.model.name
font.pointSize: 20
}
}
}
But this error shows
Type Error: Cannot read property 'name' of undefined)
What is the solution for this?
The code ListModel.model.name does not make sense since the ListModel that is a component (class) does not have that property. In this case it is better to create a property that handles the currentIndex between the pages and the model is used directly.
main.qml
import QtQuick 2.9
import QtQuick.Controls 2.2
ApplicationWindow {
id: window
visible: true
width: 640
height: 480
title: qsTr("Stack")
ListModel {
id: mymodel
ListElement {
name: 'Jack'
age: 30
rank: 'Captain'
}
ListElement {
name: 'Barbossa'
age: 23
rank: 'Sailor'
}
ListElement {
name: 'Philip'
age: 19
rank: 'Sergent'
}
}
QtObject{
id: internals
property int currentIndex: -1
}
StackView {
id: stackView
anchors.fill: parent
initialItem: "TodoView.qml"
}
}
TodoView.qml
import QtQuick 2.9
import QtQuick.Controls 2.2
Item {
ListView {
id: list
model: mymodel
anchors.fill: parent
spacing: 10
delegate: Rectangle {
width: parent.width
height: 20
color: 'Blue'
Text {
anchors.centerIn: parent
color: 'white'
text: 'Name: ' + name + ', Age: ' + age
font.pointSize: 20
}
MouseArea {
anchors.fill: parent
onClicked: list.currentIndex = index
}
Button {
width: 50
height: parent.height
anchors.right: parent.right
text: ">"
onClicked: {
list.currentIndex = index
internals.currentIndex = index
stackView.push("DetailView.qml")
}
}
}
}
}
DetailView.qml
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
Item {
Rectangle {
width: parent.width
height: 20
color: 'red'
Text {
anchors.centerIn: parent
color: 'white'
text: 'Name: ' + mymodel.get(internals.currentIndex).name
font.pointSize: 20
}
}
}
How can I change the text color of the menu items of a QML MenuBar?
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Controls.Styles 1.3 as QtQuickControlStyle
ApplicationWindow {
title: qsTr("Test")
width: 640
height: 480
visible: true
property color menuBackgroundColor: "#3C3C3C"
property color menuBorderColor: "#282828"
menuBar: MenuBar {
style: QtQuickControlStyle.MenuBarStyle {
padding {
left: 8
right: 8
top: 3
bottom: 3
}
background: Rectangle {
border.color: menuBorderColor
color: menuBackgroundColor
}
// font: // how to set font color to red?
// textColor: "red" /* does not work - results in Cannot assign to non-existent property "textColor" */
TextField { // does also not work
style: TextFieldStyle {
textColor: "red"
}
}
}
}
}
A similar question has been asked here but it seems not to work with menu items.
You have to redefine itemDelegate and itemDelegate.label for menuStyle. The former defines the style of the MenuBar text whereas the latter defines the style of menu items text.
In the following example I defined a full style for MenuBar and Menus, not only for their text. scrollIndicator is the only missing piece here. It can be represented as a Text/Label or an Image.
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Controls.Styles 1.3
import QtQuick.Window 2.2
ApplicationWindow {
title: qsTr("Test")
width: 640
height: 480
visible: true
property color menuBackgroundColor: "#3C3C3C"
property color menuBorderColor: "#282828"
menuBar: MenuBar {
Menu {
title: "File"
MenuItem { text: "Open..." }
MenuItem { text: "Close" }
}
Menu {
title: "Edit"
MenuItem { text: "Cut"; checkable: true}
MenuItem { text: "Copy" }
MenuItem { text: "Paste" }
MenuSeparator {visible: true }
Menu {
title: "submenu"
}
}
style: MenuBarStyle {
padding {
left: 8
right: 8
top: 3
bottom: 3
}
background: Rectangle {
id: rect
border.color: menuBorderColor
color: menuBackgroundColor
}
itemDelegate: Rectangle { // the menus
implicitWidth: lab.contentWidth * 1.4 // adjust width the way you prefer it
implicitHeight: lab.contentHeight // adjust height the way you prefer it
color: styleData.selected || styleData.open ? "red" : "transparent"
Label {
id: lab
anchors.horizontalCenter: parent.horizontalCenter
color: styleData.selected || styleData.open ? "white" : "red"
font.wordSpacing: 10
text: styleData.text
}
}
menuStyle: MenuStyle { // the menus items
id: goreStyle
frame: Rectangle {
color: menuBackgroundColor
}
itemDelegate {
background: Rectangle {
color: styleData.selected || styleData.open ? "red" : menuBackgroundColor
radius: styleData.selected ? 3 : 0
}
label: Label {
color: styleData.selected ? "white" : "red"
text: styleData.text
}
submenuIndicator: Text {
text: "\u25ba"
font: goreStyle.font
color: styleData.selected || styleData.open ? "white" : "red"
styleColor: Qt.lighter(color, 4)
}
shortcut: Label {
color: styleData.selected ? "white" : "red"
text: styleData.shortcut
}
checkmarkIndicator: CheckBox { // not strinctly a Checkbox. A Rectangle is fine too
checked: styleData.checked
style: CheckBoxStyle {
indicator: Rectangle {
implicitWidth: goreStyle.font.pixelSize
implicitHeight: implicitWidth
radius: 2
color: control.checked ? "red" : menuBackgroundColor
border.color: control.activeFocus ? menuBackgroundColor : "red"
border.width: 2
Rectangle {
visible: control.checked
color: "red"
border.color: menuBackgroundColor
border.width: 2
radius: 2
anchors.fill: parent
}
}
spacing: 10
}
}
}
// scrollIndicator: // <--- could be an image
separator: Rectangle {
width: parent.width
implicitHeight: 2
color: "white"
}
}
}
}
}
And here is the resulting MenuBar and Menus:
You can also choose to set a MenuStyle directly inside a Menu, in the style property. Something like this:
Menu {
title: "File"
MenuItem { text: "Open..." }
MenuItem { text: "Close" }
style: MenuStyle {
itemDelegate.label: Label {
color: "blue"
text: styleData.text
// stuff above here
}
}
In this last example only the "File" Menu items are styled with a blue color for text. One can argue how much ugly that would be, though.
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);
}