QML - Not able to canvas.requestPaint() from a function - qt

I am a beginer and i am not getting how to call canvas.requestPaint() in My QML ,Code is below:
//myTab.qml
TabView {
id: tv
width: parent.width
height: parent.height
antialiasing: true
style: TabViewStyle {
frameOverlap: -1
tab: Rectangle {
color: "Transparent"
implicitWidth: text1.width + 50
implicitHeight: 20
radius: 2
smooth: true
Canvas {
id: canvas1
anchors.fill: parent
width: parent.width
height: parent.height
onPaint: {
styleData.selected ? drawTab(canvas1,"#0C3142") :
drawTab(canvas1,"Transparent") //Some custom JS function to draw a object
}
Text {
id: text1
height: parent.height
verticalAlignment: Text.AlignVCenter
anchors.left : parent.left
anchors.leftMargin: 15
text: styleData.title
color: "white"
}
}
}
frame: Rectangle {
width: parent.width
height: parent.height
color: "Transparent"
border.color:"white"
}
tabBar: Rectangle {
color: "Transparent"
anchors.fill: parent
}
}
Tab {
id: tab1
title: "Tab1"
}
Tab{
id: tab2
title: "Tab2"
}
onCurrentIndexChanged: {
console.log("index changed "+currentIndex)
canvas1.repaint() //ERRROR - not defind canvas1
}
}
When i try to use in onCurrentIndexChanged, I am getting the following error:
ReferenceError: canvas1 is not defined.
Please Suggest.

You have the id canvas1 in another scope, as the tab-style is a Component and the ID therefore not necessarily unique for the TabView. It might be instantiated multiple times.
I have little experience with the TabView, so there might be another solution. I however would declare a signal: refresh in the TabView which I trigger, whenever I want to repaint.
Then I'd use a Connections-element within the Canvas to connect to this signal to execute the repaint
Example:
TabView {
id: tv
width: parent.width
height: parent.height
antialiasing: true
signal refresh // *** DEFINE SIGNAL HERE
style: TabViewStyle {
frameOverlap: -1
tab: Rectangle {
color: "Transparent"
implicitWidth: text1.width + 50
implicitHeight: 20
radius: 2
smooth: true
Canvas {
id: canvas1
anchors.fill: parent
width: parent.width
height: parent.height
onPaint: {
styleData.selected ? drawTab(canvas1,"#0C3142") :
drawTab(canvas1,"Transparent") //Some custom JS function to draw a object
}
function drawTab() { // *** I DONT KNOW WHAT SHOULD BE DONE HERE
console.log('do nothing')
}
// *** CONNECT TO SIGNAL HERE ***
Connections {
target: tv
onRefresh: canvas1.requestPaint() // *** repaint is not a function.
}
Text {
id: text1
height: parent.height
verticalAlignment: Text.AlignVCenter
anchors.left : parent.left
anchors.leftMargin: 15
text: styleData.title
color: "white"
}
}
}
frame: Rectangle {
width: parent.width
height: parent.height
color: "Transparent"
border.color:"white"
}
tabBar: Rectangle {
color: "Transparent"
anchors.fill: parent
}
}
Tab {
id: tab1
title: "Tab1"
}
Tab{
id: tab2
title: "Tab2"
}
onCurrentIndexChanged: {
console.log("index changed "+currentIndex)
refresh() // *** INVOKE SIGNAL HERE
}
}

Related

Text over the Swipe, how to fix?

I have ListView with items like this:
And I want use swipe. But when I add SwipeDelegate I get this:
How I can make swipe elements over the text? I try use z properties, but with z my swipe not animated when opened and I can't close it.
Here my code:
//SomePage.qml:
import QtQuick 2.12
import QtQuick.Controls 2.12
ScrollView {
ListView {
id: someListView
model: SomeItems {}
delegate: SwipeDelegate {
width: someListView.width
Row {
leftPadding: 5
width: parent.width
Image {
id: someImg
height: 38
source: myImage
width: height
}
Column {
leftPadding: 5
width: parent.width - someImg.width - 10
// Name
Text {
id: someName
text: myCount.toString() + " × " + myName
}
// Number
Text {
id: someNumber
text: myNumber.toLocaleString(Qt.locale("ru-RU"), "f", 0)
anchors.right: parent.right
font.pixelSize: 12
rightPadding: 5
}
}
}
swipe.right: Row {
anchors.right: parent.right
height: parent.height
// Delete button
Label {
text: "\ue800"
color: "black"
font.family: fontFontello.name
height: parent.height
padding: 12
verticalAlignment: Label.AlignVCenter
width: this.height
background: Rectangle {
color: "lightblue"
height: parent.height
width: parent.width
MouseArea {
anchors.fill: parent
onClicked: someListView.model.remove(index)
}
}
}
// Hide button
Label {
text: "\ue80a"
color: "black"
font.family: fontFontello.name
height: parent.height
padding: 12
verticalAlignment: Label.AlignVCenter
width: this.height
background: Rectangle {
color: "lightgray"
MouseArea {
anchors.fill: parent
onClicked: {
...
swipe.close()
}
}
}
}
}
}
}
}
The problem is you're adding your text/image on top of the default contentItem instead of inside it. It will look correct if you add your Row to contentItem, like this:
delegate: SwipeDelegate {
contentItem: Row {
...
}
}

plus button under listview

I can create "+" (plus) button under all listview items.
This button will add a new item.
I can place it under all exsisting items. But ideály as a part as list.Because of scrolling, scrollbars and other standard listview functions. If listview will be not fill all available page size, scrolls will be ended in the middle of the screan etc...
I tested counting onpaint signal or something like this, but have no success. Because signal for one row goint more than one times, counting is mismatched and button is one time in seccond row, one time below third, sometimes is missing etc...
Example image:
Source code:
import QtQuick 2.10
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.2
import QtGraphicalEffects 1.0
Page {
title: qsTr("Page 1")
anchors.fill: parent
focus: true
property int myIndex: 0
function setVisibility()
{
if(myModel.rowCount()*3 === myIndex)
{
myIndex = 0
return true
}
else
{
myIndex = myIndex + 1
return false
}
}
/*
*
*
* ListView Component
*
*
*/
ListView
{
id: listView1
model: myModel
currentIndex: 0
//property int actualHeight
anchors.fill: parent
clip: true
//spacing: 40
highlightMoveDuration: 1
highlightMoveVelocity: 1
highlightResizeDuration: 0.0
highlight: Rectangle
{
color: "#2e6377"
opacity: 0.3
}
delegate: hDelegate
}
/*
*
*
* ListViewItem Component
*
*
*/
Component
{
id: hDelegate
Item
{
width: parent.width
height: taskInfo.implicitHeight
property variant mainData: model
MouseArea
{
anchors.fill: parent
onClicked:
{
listView1.currentIndex = index
gIdd = listView1.currentItem.mainData.task_idd
gSubject = listView1.currentItem.mainData.task_subject
gBody = listView1.currentItem.mainData.task_body
listView1.currentIndex = index
}
onDoubleClicked:
{
listView1.currentIndex = index
stackView.push("page3.qml")
}
onPressAndHold:
{
listView1.currentIndex = index
stackView.push("page3.qml")
}
hoverEnabled: true
}
Row
{
id: taskInfo
spacing: 5
Rectangle
{
id: dificultStatus
height: taskColumn.height
width: taskColumn.height
color: "transparent"
Rectangle
{
id: rect22
color: "green"
width: parent.width - 20
height: parent.height - 20
radius: 15
border.color: "lightsteelblue"
border.width: 1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
}
Column
{
id: taskColumn
width: listView1.width - editButton.width - dificultStatus.width - 10
Row
{
Text
{
text: task_subject
color: "lightsteelblue"
horizontalAlignment: Text.AlignRight
wrapMode: Text.WordWrap
font {family: localFont.name; pointSize: 14; letterSpacing: 1; wordSpacing: 1}
}
Text
{
text: task_subject
color: "lightsteelblue"
wrapMode: Text.WordWrap
font {family: localFont.name; pointSize: 14; letterSpacing: 1; wordSpacing: 1}
}
}
Text
{
id: text1
height: 50
width: parent.width
clip: true
text: task_body
color: "lightsteelblue"
wrapMode: Text.WordWrap
font {family: localFont.name; pointSize: 14; letterSpacing: 1; wordSpacing: 1}
}
}
Button
{
id: editButton
height: taskColumn.height
width: taskColumn.height
background:
Rectangle
{
anchors.fill: parent
color: "transparent"
Rectangle
{
color: "transparent"
width: parent.width - 20
height: parent.height - 20
radius: 15
border.color: "lightsteelblue"
border.width: 1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
}
Text {
anchors.fill: parent
text: qsTr("...")
color: "lightsteelblue"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: 24
anchors.centerIn: parent
}
onClicked:
{
listView1.currentIndex = index
gIdd = listView1.currentItem.mainData.task_idd
gSubject = listView1.currentItem.mainData.task_subject
gBody = listView1.currentItem.mainData.task_body
listView1.currentIndex = index
stackView.push("page3.qml")
}
}
/*
*
*
* AddButton Component
*
*
*/
Button
{
height: taskColumn.height
width: taskColumn.height
x: 0
y: 80
visible: setVisibility()
//visible: (myModel.rowCount() === ++myIndex) ? true : false
background:
Rectangle
{
anchors.fill: parent
color: "transparent"
Rectangle
{
color: "transparent"
width: parent.width - 20
height: parent.height - 20
radius: 15
border.color: "lightsteelblue"
border.width: 1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
}
Text {
anchors.fill: parent
text: qsTr("+")
color: "lightsteelblue"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: 24
anchors.centerIn: parent
}
onClicked:
{
listView1.currentIndex = index
gIdd = listView1.currentItem.mainData.task_idd
gSubject = listView1.currentItem.mainData.task_subject
gBody = listView1.currentItem.mainData.task_body
listView1.currentIndex = index
stackView.push("page2.qml")
}
}
}
}
}
}
You can just use ListView's footer property. The default footerPositioning is what you want.

Drag and Drop in ListView

I am trying to drag and drop a ListView row and I am having trouble at the drag stage. Below code doesn't drag anything and name column is not aligned properly. I don't want to specify a size for ListView and I want it to get its size from its content Row with id row. It should be able to because text has size coming from its font size and Rectangle has set width. ListView can get wider as needed to show the name part.
import QtQuick 2.11
import QtQuick.Layouts 1.11
ListView {
id: root
height: scrollview.viewport.height
model: listModel
delegate: dragDelegate
Component {
id: dragDelegate
MouseArea {
id: dragArea
anchors { left: parent.left; right: parent.right }
height: content.height
drag.target: pressed ? content : undefined
drag.axis: Drag.XAndYAxis
Rectangle {
id: content
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
height: row.implicitHeight
border.width: 1
border.color: "lightsteelblue"
color: "green"
radius: 2
states: State {
when: dragArea.pressed
ParentChange { target: content; parent: root }
AnchorChanges {
target: content
anchors { horizontalCenter: undefined; verticalCenter: undefined }
}
}
Row {
id: row
Text {
text: name
font.pointSize: 15
}
Rectangle {
height: parent.height
width: 40
color: hexColor
}
}
}
}
}
ListModel {
id: listModel
ListElement {
name: "first-name"
hexColor: "red"
}
ListElement {
name: "second-name"
hexColor: "green"
}
}
}

How to get Clicked or Pressed event on QML TableView header?

I I´m trying get the click or press event on QML TableView Header.
I have tried on HeaderDelegate create a MouseArea with width, height and anchors.fill from the parent, and get the onClicked or onPressed events, but don´t work.
Example:
MouseArea {
width: parent.width
height: parent.height
anchors.fill: parent
onClicked: {
console.debug("CLICKED: "+styleData.pressed)
console.debug("COLUMN: "+ styleData.column)
}
onPressed: {
console.debug("PRESSED: "+styleData.pressed)
console.debug("COLUMN: "+ styleData.column)
}
}
that doesn't log anything
I also tried use "Connections" on HeaderDelegate, with "target: styleData" and "onPressedChanged"event, and worked, but the "onPressedChanged" get 4 changes in the same time.
Example:
Connections {
target: styleData
onPressedChanged: {
console.debug("PRESSED: "+ styleData.pressed)
console.debug("COLUMN: "+ styleData.column)
}
}
Return:
qml: PRESSED: true
qml: COLUMN: 0
qml: PRESSED: true
qml: COLUMN: 0
qml: PRESSED: false
qml: COLUMN: 0
qml: PRESSED: false
qml: COLUMN: 0
The whole code from TableView:
TableView {
id: tViewEnt
width: parent.width
height: parent.height
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
verticalScrollBarPolicy: Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
TableViewColumn {
id: column0
title: "column0"
width: 30
delegate: CheckBox {
style: CheckBoxStyle {
indicator: Rectangle {
//INDICATOR PROPERTIES
}
}
}
}
TableViewColumn {
title: "column1"
role: "column1"
}
TableViewColumn {
title: "column2"
role: "column2"
}
headerDelegate: Rectangle {
height: tViewEnt.height / 15
color: styleData.column===0 ? "#4D4D4D" : "#0077B3"
Rectangle {
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.bottomMargin: 1
anchors.topMargin: 1
width: 1
color: "#333"
}
Text {
text: styleData.value
color: "#CFF"
width: parent.width
height: parent.height
font.pointSize: 18
minimumPointSize: 3
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
Connections {
target: styleData
onPressedChanged: {
console.debug("PRESSED: "+ styleData.pressed)
console.debug("COLUMN: "+ styleData.column)
}
}
}
}
So, How do i get the Header Delegate click or pressed event in the right way?

Firebase calendar (Multi-User)

I am currently building a multi-user calendar app in Qt, and intend to use firebase realtime database to handle the user data and scheduled tasks.
Each user can login to the app and select days which, once clicking on a 'save' button, will be locked to their name. I have no previous experience with firebase and would like some help to begin structuring the database, I want to be able to separate users into departments also.
Below is the code of my calendar page on my app, what would I put into firebase to be able to connect the two?
any help would be much appreciated!!
Page {
title: "Calendar"
rightBarItem: NavigationBarItem {
contentWidth: saveButton.width
AppButton {
id: saveButton
text: "Save & Request"
anchors.right: parent.right
}
}
SystemPalette {
id: systemPalette
}
Flow {
id: row
anchors.fill: parent
spacing: 10
layoutDirection: "RightToLeft"
Calendar {
id: calendar
width: (parent.width > parent.height ? parent.width * 0.6 - parent.spacing : parent.width)
height: (parent.height > parent.width ? parent.height * 0.6 - parent.spacing : parent.height)
selectedDate: new Date()
focus: true
style: CalendarStyle {
dayDelegate: Item {
readonly property color sameMonthDateTextColor: "#444"
readonly property color selectedDateColor: Qt.platformos === "osx" ? "#3778d0" : systemPalette.highlight
readonly property color selectedDateTextColor: "white"
readonly property color differentMonthDateTextColor: "#bbb"
readonly property color invalidDatecolor: "#dddddd"
Rectangle {
anchors.fill: parent
border.color: "#00000000"
color: styleData.date !== undefined && styleData.selected? selectedDateColor : "#00000000"
anchors.margins: styleData.selected ? -1 : 0
}
Label {
id: dayDelegateText
text: styleData.date.getDate()
anchors.centerIn: parent
color: {
var color = invalidDatecolor;
if (styleData.valid) {
color = styleData.visibleMonth ? sameMonthDateTextColor : differentMonthDateTextColor ;
if (styleData.selected) {
color = selectedDateTextColor;
}
}
color ;
}
}
}
}
}
Component {
id: eventListHeader
Row {
id: eventDateRow
width: parent.width
height: eventDayLabel.height
spacing: 10
Label {
id: eventDayLabel
text: calendar.selectedDate.getDate()
font.pointSize: 35
}
Column {
height: eventDayLabel.height
Label {
readonly property var options: { weekday: "long" }
text: Qt.locale().standaloneDayName(calendar.selectedDate.getDay(), Locale.LongFormat)
font.pointSize: 18
}
Label {
text: Qt.locale().standaloneMonthName(calendar.selectedDate.getMonth())
+ calendar.selectedDate.toLocaleDateString(Qt.locale(), " yyyy")
font.pointSize: 12
}
}
}
}
Rectangle {
width: (parent.width > parent.height ? parent.width * 0.4 - parent.spacing : parent.width)
height: (parent.height > parent.width ? parent.height * 0.4 - parent.spacing : parent.height)
ListView {
id:eventListView
spacing: 4
clip: true
header: eventListHeader
anchors.fill: parent
anchors.margins: 10
model: eventModel.eventsForDate(calendar.selectedDate)
delegate: Rectangle {
width: eventListView.width
height: eventItemColumn.height
anchors.horizontalCenter: parent.horizontalCenter
Image {
anchors.top: parent.top
anchors.topMargin: 4
width: 12
height: width
source: "qrc:/images/eventindicator.png"
}
Rectangle {
width: parent.width
height: 1
color: "#eee"
}
Column {
id: eventItemColumn
anchors.left: parent.left
anchors.leftMargin: 20
anchors.right: parent.right
height: timeLabel.height + nameLabel.height + 8
Label {
id: nameLabel
width: parent.width
wrapMode: Text.Wrap
text: modelData.name
}
Label {
id: timeLabel
width: parent.width
wrapMode: Text.Wrap
text: modelData.startDate.toLocaleTimeString(calendar.locale, Locale.ShortFormat)
color: "#aaa"
}
}
}
}
}
}
}
If I understood correctly, you have not yet integrated Firebase to your Qt project?
You can have a look at this plugin for using Firebase with Qt Quick: https://v-play.net/doc/plugin-firebase/
Then you can listen to the reatimeValueChanged signal and update your calendar accordingly.

Resources