QtQuick2 - custom MessageBox - javascript

Does anyone know how to implement custom MessageBox for mobile devices? I've tried to use Window type, but with no luck (it just shows but somewhere out of screen). I appreciate if someone can show me why usage of Window doesn't work. I used also this example. But on mobile devices it doesn't work.
Here is my current code, using Window. As said, it doesn't work since it does show out of screen range.
import QtQuick 2.4
import QtQuick.Window 2.1
Item{
function showMessage(text, title)
{
messageBox.text = text;
messageBox.title = title;
messageBox.visible = true;
}
Window {
id: messageBox
modality: Qt.ApplicationModal
title: ""
visible: false
property alias text: messageBoxLabel.text
color: parent.color
minimumHeight: 100
minimumWidth: 300
Label {
anchors.margins: 10
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: messageBoxButton.top
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
id: messageBoxLabel
text: ""
}
Button {
anchors.margins: 10
id: messageBoxButton
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: "Ok"
onClicked: messageBox.visible = false
}
}
}
Can someone show me why it's working wrong?

MessageBox.qml
import QtQuick 2.2
import QtQuick.Controls 1.2
Rectangle {
id: mainWrapper
color: "#80000000"
x: 0;
y: 0;
width: parent.width;
height: parent.height;
opacity: 0;
Behavior on opacity { NumberAnimation { duration: 500; easing.type: Easing.OutExpo } }
visible: opacity > 0
property string text;
MouseArea {
anchors.fill: parent;
preventStealing: true
}
signal finished(bool ok);
function init() {
opacity = 1;
msgB.scale = 1.0;
}
Rectangle {
id: msgB
color: "#323232"
gradient: Gradient {
GradientStop { position: 0; color: "#323232" }
GradientStop { position: 1; color: "#252525" }
}
//radius: 7
width: parent.width * 0.4;
height: cont.height + 20 * 2;
anchors.centerIn: parent;
scale: 0.6
Behavior on scale { NumberAnimation { duration: 500; easing.type: Easing.OutExpo } }
Behavior on height { NumberAnimation { duration: 500; easing.type: Easing.OutExpo } }
Column {
id: cont
width: parent.width;
y: 20;
spacing: 20;
Text {
color: "#ffffff"
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
font {
bold: false;
pixelSize: 21;
}
wrapMode: Text.WordWrap;
text: mainWrapper.text;
}
Button {
anchors.margins: 10
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: "OK"
onClicked: {
mainWrapper.opacity = 0;
msgB.scale = 0.6;
mainWrapper.finished(true);
}
}
}
}
}
Somewhere in main.qml file (window is the id of main.qml element):
function message(msg, finished) {
var alert = Qt.createComponent("MessageBox.qml").createObject(window, { text: msg });
alert.onFinished.connect(function(ok) {
if (ok) {
if (finished)
finished();
}
alert.destroy(500);
});
alert.init();
return alert;
}
Use it like this:
Button {
...
onClicked: {
message("Hello world", function() { console.log("OK clicked"); });
}
}

Thanks all for answers and comments, summarizing above I created element without Window type, but with contentItem property. It's very raw element, but usable like Dialog as suggested by BaCaRoZzo or Window as in Mechan example.
Here is source:
main.qml
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.2
ApplicationWindow {
title: qsTr("Hello World")
width: Screen.width
height: Screen.height
visible: true
id: win
color: brPalette.charcoal
BreezeQuickMessageBox{
id: mbox
palette: brPalette
contentItem: Rectangle{
color: "lightblue"
anchors.fill: parent
BreezeQuickButton{
id: btn
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
palette: brPalette
gradiented: false
onClicked: {
mbox.hide()
}
}
}
}
/*
Another bunch of code
*/
BreezeQuickPalette{
id: brPalette
theme: "dark"
}
}
BreezeQuickMessageBox.qml
import QtQuick 2.4
Item {
id: root
property BreezeQuickPalette palette: BreezeQuickPalette
property bool __buttonGradiented: false
property string title: "Message Box"
property Item contentItem
anchors.fill: parent
Behavior on opacity {
NumberAnimation{
duration: 250
}
}
opacity: 0
visible: opacity > 0
z: parent.z + 100
BreezeQuickPalette{
id: __palette
theme: palette.theme
}
Rectangle {
id: window
width: parent.width
height: parent.height*0.4
anchors {
verticalCenter: parent.verticalCenter
}
z: parent.z + 1
color: palette.charcoal
Item {
id: content
width: parent.width
anchors {
top: titleText.bottom
bottom: line.top
horizontalCenter: parent.horizontalCenter
topMargin: 8
bottomMargin: 8
}
children: contentItem
}
Rectangle{
id: line
width: parent.width
anchors{
bottom: buttonArea.top
horizontalCenter: parent.horizontalCenter
}
height: 1
color: palette.focusColor
}
Text{
id: titleText
font.pointSize: buttonOk.font.pointSize
color: palette.normalText
text: title
anchors {
top: parent.top
horizontalCenter: parent.horizontalCenter
topMargin: 16
}
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
Rectangle{
id: buttonArea
width: parent.width
anchors{
horizontalCenter: parent.horizontalCenter
bottom: window.bottom
}
height: buttonOk.height*1.2
color: "transparent"
}
BreezeQuickButton {
id: buttonOk
caption: "Ok"
width: 128
palette: __palette
gradiented: __buttonGradiented
anchors{
horizontalCenter: parent.horizontalCenter
verticalCenter: buttonArea.verticalCenter
}
onClicked: {
root.hide()
}
}
}
Rectangle{
id: shadow
anchors.fill: parent
z: parent.z
color: palette.shadeBlack
opacity: 0.4
MouseArea{
id: rootArea
anchors.fill: parent
hoverEnabled: true
}
gradient: Gradient {
GradientStop { position: 0.0; color: palette.black }
GradientStop { position: 0.1; color: palette.shadeBlack }
GradientStop { position: 0.3; color: palette.grey }
GradientStop { position: 0.7; color: palette.grey }
GradientStop { position: 0.9; color: palette.shadeBlack }
GradientStop { position: 1.0; color: palette.black }
}
}
function show (title, message) {
root.opacity = 1
}
function hide () {
root.opacity = 0
}
}
And actual look for Android:

Related

How to close a popup QML after the animation has run?

I have two animations in my popup component, one runs when I open the popup and the other should run when I close it. Both animations work correctly, my current problem is that the animation runs after closing the popup, so it is not visible while the component is open.
Is there any way to close the popup only after running the animation?
Or a way to close the popup on click after a certain time?
Here is my popup component with the animations
import QtQuick 2.12
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Popup {
id: popup
width: 392
height: 768
parent: Overlay.overlay
modal: true
dim: true
closePolicy: Popup.NoAutoClose
x: Math.round((parent.width - popup.width))
y: Math.round((parent.height - popup.height) / 2)
Overlay.modal: Item {
id: overlay
width: popup.width
height: popup.height
Rectangle {
id: opacityBackground
anchors.fill: parent
color: "#000000"
opacity: 0
PropertyAnimation on opacity {
to: 0.4; duration: 3000;
}
}
}
background: Rectangle {
id: backgroundRectangle
implicitWidth: popup.width
implicitHeight: popup.height
color: "#0D0D0D"
}
Item {
id: content
anchors.fill: parent
Item {
id: header
width: popup.width - 4
height: 72
anchors.top: parent.top
anchors.left: parent.left
anchors.topMargin: - 4
anchors.leftMargin: - 4
Item {
width: 105
height: 72
anchors.left: parent.left
anchors.top: parent.top
}
NbIconButton {
iconSource: "/icons/cancel.svg"
anchors.top: parent.top
anchors.right: parent.right
buttonColor: "#0D0D0D"
onClicked: {
slideOut.start()
popup.close()
}
}
}
Item {
id: descriptionContainer
width: 285
height: 88
anchors.top: parent.top
anchors.topMargin: 118
anchors.horizontalCenter: parent.horizontalCenter
}
Item {
id: tableContainer
anchors.top: contentTitle.bottom
anchors.topMargin: 24
}
}
onOpened: {
slideIn.start()
}
onClosed: {
slideOut.start()
}
ParallelAnimation {
id: slideIn
PropertyAnimation {
target: overlay
property: "opacity"
to: 0
duration: 3000
}
NumberAnimation {
target: popup
property: "x"
from: parent.width
to: 632
duration: 3000
easing.type: Easing.OutCubic
}
}
ParallelAnimation {
id: slideOut
PropertyAnimation {
target: opacityBackground
property: "opacity"
to: 0
duration: 3000
}
NumberAnimation {
target: popup
property: "x"
from: 632
to: parent.width
duration: 3000
easing.type: Easing.OutCubic
}
}
}

TextField hover highlight animation QML QtQuick.Control 2.15

I have a textfield and I am trying to highlights its background when hovered. I am using a PropertyAnimation and it does not really do the animation:
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15
TextField {
id: txtfield
height: 40
width: 250
QtObject{
id: internal
// property var dynamicWidth: {if(txtfield.hovered){
// console.log('Damn')
// bg.border.width = 1.5
// }else{
// bg.border.width = 0
// }
// }
}
color: '#ffffff'
placeholderTextColor: "#7fffffff"
selectedTextColor: '#000000'
selectionColor: '#ffffff'
font.family: "Verdana"
font.pointSize: 10
placeholderText: qsTr('Enter full name...')
hoverEnabled: true
background: Rectangle{
id: bg
color: "#2c313c"
border.color: "#aa0000"
// border.width: internal.dynamicWidth
radius: 10
PropertyAnimation{
id: widthAnimation
target: bg // rectangle
property: 'border.width'
to: if(txtfield.hovered){
return 10
}else{
return 0
}
duration: 500
easing.type: Easing.InOutQuint
} }
}
I am new and just learning JS, thanks in advance :D
The animation won't start when the txtfiled.hovered property changes as you expect. To start the animation you should use the start() method. Solution 1:
TextField {
id: txtfield
anchors.centerIn: parent
height: 40
width: 250
QtObject{
}
color: '#ffffff'
placeholderTextColor: "#7fffffff"
selectedTextColor: '#000000'
selectionColor: '#ffffff'
font.family: "Verdana"
font.pointSize: 10
placeholderText: qsTr('Enter full name...')
MouseArea {
anchors.fill: parent
hoverEnabled: true
onHoveredChanged: {
if (containsMouse) {
widthAnimation.start();
} else {
bg.border.width = 0;
}
}
onClicked: {
txtfield.forceActiveFocus();
}
}
background: Rectangle{
id: bg
color: "#2c313c"
border.color: "#aa0000"
// border.width: internal.dynamicWidth
radius: 10
PropertyAnimation{
id: widthAnimation
target: bg // rectangle
property: 'border.width'
to: 10
duration: 500
easing.type: Easing.InOutQuint
}
}
}
Now, you may want to have an animation when the mouse leaves the TextArea. This is better to do using states and transitions:
TextField {
id: txtfield
anchors.centerIn: parent
height: 40
width: 250
QtObject{
id: internal
}
color: '#ffffff'
placeholderTextColor: "#7fffffff"
selectedTextColor: '#000000'
selectionColor: '#ffffff'
font.family: "Verdana"
font.pointSize: 10
placeholderText: qsTr('Enter full name...')
MouseArea {
anchors.fill: parent
hoverEnabled: true
onHoveredChanged: {
if (containsMouse) {
bg.state = "hovered"
} else {
bg.state = "unhovered"
}
}
onClicked: {
txtfield.forceActiveFocus();
}
}
background: Rectangle{
id: bg
color: "#2c313c"
border.color: "#aa0000"
radius: 10
states: [
State {
name: "hovered"
PropertyChanges {
target: bg
border.width: 10
}
},
State {
name: "unhovered"
PropertyChanges {
target: bg
border.width: 0
}
}
]
transitions: [
Transition {
from: "*"
to: "*"
PropertyAnimation {
property: "border.width"
duration: 300
easing.type: Easing.InOutQuint
}
}
]
}
}
More about states and transitions: https://doc.qt.io/qt-5/qml-tutorial3.html

How to get column data from QtQuickControls 1 with TableView in QML?

I am using import QtQuick.Controls 1.4 as CC. Whenever I click on first column, the output I get is undefined whereas I am able to get the data of the rest of the columns.
That first column has a delegate.
What is the way to get data from the first column which has a delegate?
import QtQuick.Window 2.12
import QtQuick 2.12
import QtQuick.Controls 1.4 as CC
import QtQuick.Controls.Styles 1.4
Window
{
visible: true
width: 640
height: 480
title: qsTr("Hello World")
CC.TableView
{
height: 400; width: 600
style: TableViewStyle
{
headerDelegate: Rectangle
{
height: 20
color: "lightsteelblue"
Text
{
width: parent.width
text: styleData.value
}
}
rowDelegate: Rectangle
{
color: "blue"
height: 30
MouseArea
{
id: ma
anchors.fill: parent
onClicked:
{
console.log(styleData.value)
}
}
}
itemDelegate: Rectangle
{
color: "blue"
height: 30
Text
{
text: styleData.value
}
MouseArea
{
id: ma1
anchors.fill: parent
onClicked:
{
console.log(styleData.value)
}
}
}
}
CC.TableViewColumn
{
role: "aaa"
title: "AAA"
width: 100
delegate: Item
{
Rectangle
{
anchors.left: parent.left
id: pic
radius: 100
height: 15; width: 15; color: "red"
}
Text
{
anchors.left: pic.right
anchors.leftMargin: 10
text: styleData.value
}
}
}
CC.TableViewColumn
{
role: "bbb"
title: "BBB"
width: 100
}
CC.TableViewColumn
{
role: "ccc"
title: "CCC"
width: 100
}
model: ListModel
{
id: mymodel
ListElement
{
aaa : "Banana1"
bbb : "Apple1"
ccc : "zzz1"
}
ListElement
{
aaa : "Banana2"
bbb : "Apple2"
ccc : "zzz2"
}
}
}
}
For the old (edited) question:
You should use styleData.row instead of styleData.value in the console log lines
For the new question:
Your column has a delegate, which overrides the item delegate of the table. Then, when the first column is clicked, it is actually the delegate of the row which calls console log.
You can fix that by changing the column delegate to:
CC.TableViewColumn
{
role: "aaa"
title: "AAA"
width: 100
delegate: Item
{
Rectangle
{
anchors.left: parent.left
id: pic
radius: 100
height: 15; width: 15; color: "red"
}
Text
{
id: text_id
anchors.left: pic.right
anchors.leftMargin: 10
text: styleData.value
}
MouseArea
{
id: ma2
anchors.fill: parent
onClicked: {
console.log(text_id.text)
}
}
}
}

headerDelegate QML tableView - text not visible

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
Window {
visible: true
width: 640
height: 480
color:"#292a38"
TableView
{
width: 580
headerDelegate: Rectangle
{
id: header1
height: 20;
color: "#343848"
}
rowDelegate: Rectangle
{
height: 30
}
TableViewColumn
{
role: "selectall"
title: ""
width: 40
delegate:
Rectangle
{
height: 120
width: 120
color: "#24253c"
}
}
TableViewColumn
{
role: "name"
title: "Name"
width: 145
delegate:
Rectangle
{
height: 120
width: 120
color: "#24253c"
RowLayout
{
spacing: 10
height: 20
width: 20
Image
{
height: 20
width: 20
}
Text
{
color: "lightgray"
text: "something"
}
}
}
}
TableViewColumn
{
role: "size"
title: "Size"
width: 100
delegate: Rectangle
{
height: 120
width: 120
color: "#24253c"
}
}
TableViewColumn
{
role: "last_updated"
title: "Last Updated"
width: 300
delegate: Component
{
Rectangle
{
height: 100
width: 150
id: head
color: "#24253c"
RowLayout
{
spacing: 10
height: parent.height
width: parent.width
Text {
id: name
text: Date().toLocaleString()
color: "lightgray"
}
Image
{
height: 20
width: 20
MouseArea
{
anchors.fill: parent
onClicked: parent.color = "grey"
}
}
}
}
}
}
model: ListModel
{
id: mymodel
ListElement { text: "Banana" }
ListElement { text: "Apple" }
ListElement { text: "Coconut" }
}
}
}
This results in:
As you can see the titles of the header are not visible. Please help.
Header delegates are to be written inside TableViewStyle with style property and then we are supposed to use styleData.value to get the value of individual column titles in the header.
TableView
{
width: 580
style: TableViewStyle
{
headerDelegate: Rectangle
{
height: 20
color: "lightsteelblue"
Text {
width: parent.width
text: styleData.value // <---
elide: Text.ElideMiddle
}
}
itemDelegate: Rectangle
{
color: "red"
Text {
width: parent.width // <---
text: styleData.value
elide: Text.ElideMiddle
}
}
rowDelegate: Rectangle
{
color: "blue"
height: 30
}
}
TableViewColumn
{
role: "selectall"
title: "XYZ"
width: 40
}
}

QML Text wrap in TableView

I want the text in each itemDelegate to wrap when it exceeds the width of the cell. It does that as needed but the overflow causes text to overlap with other cells and clipping. I know that the row height has to increase and I have to define a rowDelegate for this behaviour.
My best idea was to monitor the Text's "onContentHeightChanged" signal handler with some logic, get the index of the row the itemDelegate belongs to and then somehow change the height of the rowDelegate which I would find using the index. My attempts couldn't even bring me close to that (lots of syntax errors [relatively new to QML] and I don't see a way to get individual rows from a TableView). This is my table so far which reproduces the wrapping issue:
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
Item
{
width: 600; height: 300
ListModel{
id: myModel
ListElement{
column1: "Apple"
column2: "Bat"
column3: "Car"
}
ListElement{
column1: "Some random"
column2: "Latin"
column3: "Below this row"
}
ListElement{
column1: "Lorem ipsum dolor sit amet, at vim atqui ocurreret"
column2: "te quod postea"
column3: "moderatius pro, detracto noluisse"
}
}
TableView{
id: myTable
model: myModel
width: parent.width; height: parent.height
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
TableViewColumn{
id: col1
role: "column1"
title: "Column 1"
}
TableViewColumn{
id: col2
role: "column2"
title: "Column 2"
}
TableViewColumn{
id: col3
role: "column3"
title: "Column 3"
}
//Spaces columns to span the entire viewport
onWidthChanged: {
col1.width = 0.50 * width
col2.width = 0.30 * width
col3.width = 0.20 * width
}
//Table Styling from this point on...
style: TableViewStyle{
id: tableStyle
backgroundColor: "#e3ecf4"
alternateBackgroundColor: "#fff"
textColor: "#000"
}
Rectangle {
id: tableFrameTop
anchors{
right: parent.right
left: parent.left
top: parent.top
}
height: 1
color: "#a2a2a2"
}
headerDelegate: Rectangle{
width: headerText.implicitWidth
height: headerText.implicitHeight * 1.2
gradient: Gradient{
GradientStop{position: 1.0; color: "#dadada"}
GradientStop{position: 0.0; color: "#f9f9f9"}
}
Text{
id: headerText
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: styleData.value
color: "#292929"
font{
pixelSize: 15
weight: Font.DemiBold
}
}
Rectangle {
id: headerColSeparator
anchors{
right: parent.right
top: parent.top
bottom: parent.bottom
bottomMargin: 1
topMargin: 1
}
width: 1
color: "#cccccc"
}
Rectangle {
id: headerBottomBorder
anchors{
right: parent.right
left: parent.left
bottom: parent.bottom
}
height: 1
color: "#a2a2a2"
}
}
itemDelegate: Rectangle{
id: itemRect
anchors.fill: parent
color: "transparent"
Text {
id: itemText
text: styleData.value
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 14
color: "#292929"
// elide: Text.ElideRight
wrapMode: Text.WordWrap //Wrapping text in itemDelegate
}
Rectangle {
id: itemGridRight
anchors{
right: parent.right
top: parent.top
bottom: parent.bottom
}
width: 1
color: "#cccccc"
}
}
//Todo: create horizontal grid lines in rowDelegate
/*rowDelegate: Rectangle{
}*/
}
}
How can I get the rows to change their heights when I have text wrapping?

Categories

Resources