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);
}
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:
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
}
}
}
}
}
}
}
}
}
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
}
}
}
I've got a draggable object that is created by a Javascript, which is working fine. But when I create a PieMenu inside it, the object isn't created/visible in the Javascript context:
import QtQuick 2.8
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4
import QtQml.Models 2.2
Rectangle {
id: rev
width: 100
height: 80
color: "transparent"
antialiasing: false
Drag.active: dragArea.drag.active
MouseArea {
id: dragArea
width: parent.width
height: parent.height + 10 // easier to get
anchors.centerIn: parent
drag.target: parent
drag.axis: Drag.XAndYAxis
onClicked: pieMenu.popup(mouseX, mouseY), console.log("clicked")
}
PieMenu {
id: pieMenu
MenuItem {
text: "Add vertical bar"
onTriggered: print("Action 2")
}
}
Gauge {
id: revgauge
anchors.fill: parent
anchors.margins: 10
orientation : Qt.Horizontal
minorTickmarkCount: 4
tickmarkStepSize : 5000
minimumValue: 0
maximumValue: 10000
Behavior on value {
NumberAnimation {
duration: 5
}
}
Text {
font.pixelSize: (parent.height / 3)
anchors.top : parent.top
font.bold: true
font.family: "Eurostile"
color: "white"
anchors.horizontalCenter: parent.horizontalCenter
}
style: GaugeStyle {
valueBar: Rectangle {
implicitWidth: rev.height /3
color: Qt.rgba(revgauge.value / revgauge.maximumValue, 0, 1 - revgauge.value / revgauge.maximumValue, 1)
}
}
}
}
Can Mousearea handle dragging and a PieMenu at once? If not how can it be solved?
Consider QML PieMenu boundingItem. It addresses an exact issue with MouseArea you presented.
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)
}
}