I want to set my fullscreen app on one of my screens, so I have to set its height,width, x,y and so on. However I found the animation doesn't work.
I ever thought this caused by I set it on one targeted screen, so I create a test code, here I hard code the x,y, but the animation still doesn't work, can someone tell me why?
My test code is as following:
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
visible: true
title: qsTr("Hello World")
flags: Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint
opacity: 0.6
id: root
MouseArea {
anchors.fill: parent
onClicked: {
//Qt.quit();
}
}
Component.onCompleted: {
root.x = 0;
root.y = 0;
root.width = Screen.width;
root.height = Screen.height;
initWindow.start();
}
PropertyAnimation {
id: initWindow
target: root
from: 0
to: Screen.height
duration: 2000
easing.type: Easing.InOutQuad
onRunningChanged: {
if(!initWindow.running && root.visibility != Window.Hidden){
console.log("here is initWindow animation.")
}
}
}
}
Because you do not animate anything.
You need to specify a target.
Just a wild guess, but you probably want to animate the height?
Window {
id: root
visible: true
title: qsTr("Hello World")
// opacity: 0.6 // Does not work for me
// I want to have the frames and stuff for an example.
MouseArea {
anchors.fill: parent
onClicked: {
//Qt.quit();
}
}
Component.onCompleted: {
root.x = 0;
root.y = 0;
root.width = 1200;
root.height = 800;
}
Behavior on height { // Starts the Animation with the set target, once the height is set to be changed
NumberAnimation {
id: initWindow
duration: 200000
}
}
}
Or to stay closer to your code:
Window {
id: root
visible: true
title: qsTr("Hello World")
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
Component.onCompleted: {
root.x = 0;
root.y = 0;
root.width = Screen.width;
initWindow.start();
}
PropertyAnimation {
id: initWindow
target: root
from: 0
to: Screen.height
property: 'height' // You need to declare which property should change.
duration: 2000
easing.type: Easing.InOutQuad
}
}
See the comments, for what I did.
And I striped your code of some stuff unnecessary for an example.
Related
I need to call a C++ class method with parameters from UI after animation of SwipeView ends.
main.ui
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
SwipeView {
id: swipeView
anchors.fill: parent
Page1 {
id: page1
}
Page2{
id: page2
}
}
XOR {
id: xor
onXorEnded: {
//swipeView.setCurrentIndex(0)
}
onQChanged: {
page2.bar.value = xor.getq()
}
}
}
Page1Form.ui.qml
Page1Form {
kpButton.onClicked: {
kpDialog.visible = true
}
xorButton.onClicked: {
swipeView.setCurrentIndex(1)
xor.crypt(file_path.text, key_path.text, out_path.text)
}
fpButton.onClicked:{
fpDialog.visible = true
}
FileDialog {
id: fpDialog
onAccepted: {
file_path.text = fpDialog.fileUrl
}
}
FileDialog {
id: kpDialog
onAccepted: {
key_path.text = kpDialog.fileUrl
}
}
}
It seems like in xorButton.onClicked xoring starting before animation of swipe view ends. How it works now: Imgur
As a workaround you can bind your action to index changing:
xorButton.onClicked: {
swipeView.setCurrentIndex(1)
}
SwipeView {
id: swipeView
onCurrentItemChanged: {
if(currentIndex == 1)
xor.crypt(file_path.text, key_path.text, out_path.text)
}
}
But anyway, that fires not at end of animation.
As another workaround you can use StackView. It has more properties to control the animation. Another advantage of this control is that user cannot swipe it when you don't expect it. In your case an user just can swipe that. One more advantage is that page doesn't take memory when you don't need it.
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
Window {
visible: true
width: 800
height: 800
StackView {
id: view
anchors.fill: parent
initialItem: page1
onBusyChanged: {
if(!busy && currentItem.objectName == "page2")
currentItem.run();
}
}
Component {
id: page1
Rectangle {
color: "green"
objectName: "page1"
Button {
anchors.centerIn: parent
text: "swipe me"
onClicked:
view.push(page2)
}
}
}
Component {
id: page2
Rectangle {
color: "yellow"
objectName: "page2"
function run() { sign.visible = true; }
Rectangle {
id: sign
anchors.centerIn: parent
width: 100
height: 100
radius: 50
color: "red"
visible: false
}
}
}
}
I am trying to get my board to flash green when a button is clicked.
I have added the following color animation code to help create the flashing effect, so that the board can go from its original colors, to green, and back to it's original colors.
I have seen in some code examples where ColorAnimation can also be used like this ColorAnimation on color{...}. I tried using this to reference the rectangle color property but it complains about color being an invalid property, which is why i don't have it in the code below.
SequentialAnimation
{
running: true
loops: Animation.Infinite
ColorAnimation
{
to: "green"
duration: 500
}
ColorAnimation
{
to: "transparent"
duration: 500
}
}
The code fragment above has gone into the repeater code below. The code below handles displaying my board with the black and white colors I am starting off with.
Repeater
{
id: board
model: 64
Rectangle
{
color: getWhiteOrBlack(index)
opacity: 0.45
width: getSquareSize()
height: getSquareSize()
x: getX(index)
y: getY(index)
MouseArea
{
anchors.fill: parent
onClicked:
{
pawn.x = parent.x
pawn.y = parent.y
if (starting_position == false)
{
starting.x = parent.x
starting.y = parent.y
starting_position = true
starting_index = index
ending.visible = false
}
else
{
ending.visible = true
ending.x = parent.x
ending.y = parent.y
ending_index = index
Board.move(getRow(starting_index), getColumn(starting_index), getRow(ending_index), getColumn(ending_index))
starting_position = false
}
}
}
SequentialAnimation
{
running: true
loops: Animation.Infinite
ColorAnimation
{
to: "green"
duration: 500
}
ColorAnimation
{
to: "transparent"
duration: 500
}
}
}
}
However, whenever I click on the button that is supposed to trigger the green flash, it doesn't flash.
I don't know how to get the flashing to work when a button is clicked and would greatly appreciate any help on how to accomplish this, thanks.
You need to declare the animated property since color property can be not only color but, for example background etc.
So usual it have to be :
Rectangle {
color: "green"
ColorAnimation on color {
to: "red"
duration: 1000
}
}
But when you use it in inside SequentialAnimation you lose link to property and in this case you can just use PropertyAnimation since ColorAnimation is particular case of it:
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
id: screen
width: 400
height: 300
visible: true
Rectangle {
id: light
width: 50
height: 50
radius: 25
color: "green"
anchors.centerIn: parent
SequentialAnimation {
id: anim
PropertyAnimation {
target: light
property: "color"
to: "red"
duration: 1000
}
PropertyAnimation {
target: light
property: "color"
to: "green"
duration: 1000
}
}
MouseArea {
anchors.fill: parent
onClicked: {
anim.running = true;
}
}
}
}
I tried to change the example given here (http://qt-project.org/doc/qt-4.8/qml-flipable.html) to obtain the same effect. It happens that when I enter with the mouse in front, the signals onEntered and onExited are captured several times: Ex: Passing the mouse over, appears on the console:
Entered
Exited
Entered
If step very quickly the mouse over, the flip is performed, but remains in the second state even if the mouse is no longer in that area. Help?
Flipable {
id: flipable
width: 240
height: 240
property bool flipped: false
front: Rectangle {
color: "red";
anchors.centerIn: parent
MouseArea {
anchors.fill: parent
onEntered: {
console.log("Entered");
flipable.flipped = !flipable.flipped
}
}
}
back: Rectangle {
source: "blue";
anchors.centerIn: parent
MouseArea {
anchors.fill: parent
onExited: {
console.log("Exited");
flipable.flipped = !flipable.flipped
}
}
transform: Rotation {
id: rotation
origin.x: flipable.width/2
origin.y: flipable.height/2
axis.x: 0; axis.y: 1; axis.z: 0
angle: 0
}
states: State {
name: "back"
PropertyChanges { target: rotation; angle: 180 }
when: flipable.flipped
}
transitions: Transition {
NumberAnimation { target: rotation; property: "angle"; duration: 1000 }
}
}
First I must blame You that your example is not working.
Ok, so do not put MouseArea inside front and back as their width is dynamically changed and borders are touching your mouse generating entered and exited signals. You must set MouseArea as parent or sibling. Then you can use entered and exited signals or containsMouse property.
import QtQuick 2.0
MouseArea
{
id: mouseArea
width: 240
height: 240
hoverEnabled: true
onEntered:
{
console.log("Entered");
flipable.flipped = !flipable.flipped
}
onExited:
{
console.log("Exited");
flipable.flipped = !flipable.flipped
}
Flipable
{
id: flipable
width: 240
height: 240
property bool flipped: false
//property bool flipped: mouseArea.containsMouse // uncoment if onEntered and onExited is commented
front: Rectangle
{
color: "red";
anchors.fill: parent
}
back: Rectangle
{
color: "blue";
anchors.fill: parent
}
transform: Rotation
{
id: rotation
origin.x: flipable.width/2
origin.y: flipable.height/2
axis.x: 0; axis.y: 1; axis.z: 0
angle: 0
}
states: State
{
name: "back"
PropertyChanges { target: rotation; angle: 180 }
when: flipable.flipped
}
transitions: Transition
{
NumberAnimation { target: rotation; property: "angle"; duration: 1000 }
}
}
}
In traditional Qt (QWidget) I have one QMainWindow and some dynamically created QWidgets with the content and I change them that one was seen in main windows. What are the ways of achieving when I have couple qml files and I wants to be able to switch between them when eg clicking a button.
There are at least 3 options for solving this problem:
You can use the ready for this purpose component StackView. The point is that you will create 2 components at once and you'll be able to change them by clicking on the button.
Example:
import QtQuick 2.12
import QtQuick.Controls 2.5
ApplicationWindow {
id: window
visible: true
width: 640
height: 480
title: qsTr("Stack")
header: ToolBar {
contentHeight: toolButton.implicitHeight
ToolButton {
id: toolButton
text: stackView.depth > 1 ? "\u25C0" : "\u2630"
font.pixelSize: Qt.application.font.pixelSize * 1.6
onClicked: {
if (stackView.depth > 1) {
stackView.pop()
} else {
drawer.open()
}
}
}
Label {
text: stackView.currentItem.title
anchors.centerIn: parent
}
}
Drawer {
id: drawer
width: window.width * 0.66
height: window.height
Column {
anchors.fill: parent
ItemDelegate {
text: qsTr("Page 1")
width: parent.width
onClicked: {
stackView.push("Page1Form.qml")
drawer.close()
}
}
ItemDelegate {
text: qsTr("Page 2")
width: parent.width
onClicked: {
stackView.push("Page2Form.qml")
drawer.close()
}
}
}
}
StackView {
id: stackView
initialItem: "HomeForm.qml"
anchors.fill: parent
}
}
Use the Loader here you will dynamically load files during execution, the disadvantage of this method is that if you switch often, it will be time consuming.
Example:
import QtQuick 2.0
Item {
width: 200; height: 200
Loader { id: pageLoader }
MouseArea {
anchors.fill: parent
onClicked: pageLoader.source = "Page1.qml"
}
}
You can create a class in C++ that will be given to an already initialized QML object to an empty qml form. thus, mono place individual components into libraries and use them as plugins (use qqmlcomponent).
I would use a simple Loader, with a button that when is clicked, changes the source file of the Loader. Like so :
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
Window {
id: root
Rectangle {
id: page_main
color: "#202020"
anchors.fill : parent
Button {
id: button_page_1
width: 105
text: qsTr("Page 1")
anchors {
left: parent.left
top: parent.top
leftMargin: 6
topMargin: 0
}
checkable: true
onClicked: {
if (loader_main.source == "/page_1.qml") {
loader_main.source = ""
} else {
loader_main.source = "/page_1.qml"
button_page_2.checked = false
button_page_3.checked = false
}
}
}
Button {
id: button_page_2
width: 105
text: qsTr("Page 2")
anchors {
left: button_auto.right
top: parent.top
leftMargin: 6
topMargin: 0
}
checkable: true
onClicked: {
if (loader_main.source == "/page_2.qml") {
loader_main.source = ""
} else {
loader_main.source = "/page_2.qml"
button_page_1.checked = false
button_page_3.checked = false
}
}
}
Button {
id: button_page_3
width: 105
text: qsTr("Page 3")
anchors {
left: button_manual.right
top: parent.top
leftMargin: 6
topMargin: 0
}
checkable: true
onClicked: {
if (loader_main.source == "/page_page_3.qml") {
loader_main.source = ""
} else {
loader_main.source = "/page_page_3.qml"
button_page_1.checked = false
button_page_2.checked = false
}
}
}
}
Loader {
id: loader_main
y: 60
visible: true
anchors {
top: parent.top
bottom: parent.bottom
right: parent.right
left: parent.left
topMargin: 48
bottomMargin: 0
leftMargin: 0
rightMargin: 0
}
}
}
I have a simple list view. I need the user to be able to manipulate the font size (visual impairment issues). QML quite happily calculates new width and height for the listView items but since the strings are different lengths that leads to listView that looks like badly stacked boxes. What I need is for it to look like a rectangle the width of the longest string and wrap if it reaches the edge of the window. I figure I make the listView item backgrounds transparent and calculate the width of the rectangle the listView is in to fit the updated font size. I have tried a few ways to do this and have not managed to make it work.
Any clues? code below (data coming from c++)
import QtQuick 2.0
Rectangle
{
id: theMenu
property double fontSize: menuManager.menuFontPointSize
property double menuWidth: menuManager.menuItemHeight
Component
{
id: menuEntryDelegate
Rectangle
{
id: menuItemContainer
width: menuEntry.width
height: menuEntry.height * 1.25
anchors.top: prompts.bottom
property double fontSize: theMenu.fontSize
state: ListView.isCurrentItem ? "selected" : "notselected"
Text
{
id: menuEntry
font.pointSize: fontSize
//width: parent.width
wrapMode: Text.WordWrap
text: displayText
clip: true
}
MouseArea
{
hoverEnabled: false
anchors.fill: parent
onClicked: menuHolder.currentIndex = index
onDoubleClicked: menuManager.displayMenu(menuHolder.currentIndex)
}
states:
[
State
{
name: "selected"
PropertyChanges
{
target: menuItemContainer
color: "#FAFCD9"
}
PropertyChanges
{
target: icon
source: iconUrl
}
PropertyChanges
{
target: prompts
text: getPrompt()
}
PropertyChanges
{
target: menuEntry
color: "black"
}
},
State
{
name: "notselected"
PropertyChanges
{
target: menuItemContainer
color: "black"
}
PropertyChanges
{
target: menuEntry
color: "white"
}
},
State
{
name: "hidden"
PropertyChanges
{
target: menuItemContainer
color: "green"
}
}
]
}
}
Rectangle
{
id: menuContainer
width: menuManager.menuWidth
height: (50 * 9) //TBD
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: prompts.bottom
color: "purple"
ListView
{
id: menuHolder
model: menuModel
anchors.fill: parent
opacity: 1
/* header: Rectangle
{
TextBox {}
}*/
header: Rectangle
{
width: menuHolder.width
height: 50
color: "#2A51A3"
Text
{
id: header
anchors.centerIn: parent
text: "FIX" + currentMenu.displayText
font.pointSize: currentMenu.fontPointSize
color: "green"
width: parent.width
wrapMode: Text.WordWrap
}
}
delegate: menuEntryDelegate
focus: true
add: Transition
{
NumberAnimation { properties: "x,y" }
}
Keys.onPressed:
{
if(event.key === Qt.Key_F1)
{
theMenu.z = -1
}
else if(event.key === Qt.Key_F3)
{
theMenu.z = 1
}
else if(event.key === Qt.Key_F2)
{
menuManager.menuFontPointSize *= menuManager.scale
theMenu.fontSize = menuManager.menuFontPointSize
}
else if(event.key === Qt.Key_F10)
{
scaleFactor -= 0.1
menuContainer.scale = scaleFactor
promptsContainer.scale = scaleFactor
//promptsContainer.z = 1
}
else if(event.key === Qt.Key_Right)//zoom in
{
menuContainer.x +=10
}
else if(event.key === Qt.Key_Left)//zoom out
{
menuContainer.x -=10
}
else if(event.key === Qt.Key_Home)//go back to Main menu
{
menuManager.displayMainMenu();
theMenu.fontSize = menuManager.menuFontPointSize
}
//Ways to select a menu item
else if((event.key >= Qt.Key_1 && event.key <= Qt.Key_9)
|| event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
{
if(event.key >= Qt.Key_1 && event.key <= Qt.Key_9)
{
menuHolder.currentIndex = event.key - Qt.Key_1;
}
menuManager.displayMenu(menuHolder.currentIndex);
theMenu.fontSize = menuManager.menuFontPointSize
}
menuEntryDelegate.updateIcon()
}
}
}
}#
Just use :
width: parent.width;
In menuItemContainer Rectangle element in your delegate component, to fill the ListView width.
And then add :
anchors { left: parent.left; right: parent.right }
To menuEntry Text element to give it a max size, so it can know when it must wrap (it will extend to the right infinitely else).