A separate menu for each page - Qt and Android - android

I'm using ApplicationWindow and StackView to provide multiple pages to a user.
import QtQuick 2.0
import QtQuick.Controls 1.0
ApplicationWindow
{
menuBar: MenuBar {
Menu {
title: qsTr("Menu")
MenuItem
{
text: qsTr("Enter page")
onTriggered: stackView.push("qrc:/qml/SecondPage.qml")
}
MenuItem
{
text: qsTr("Base screen option")
onTriggered: /**/
}
}
}
StackView
{
id: stackView
anchors.fill: parent
focus: true
initialItem: FirstPage {}
}
}
When SecondPage is pushed to the stackView, the global menu is still displayed. I tried making StackView the top element and pushing ApplicationWindow there, but the StackView component needs a parent.
Is there any way to implement a page-specific menu?

Try and use properties in the ApplicationWindow to specify what text to show. Then these properties can be set in the pages in the stack view.
ApplicationWindow {
id: rootWindow
width: 360
height: 360
visible: true
property string option1Text: "Enter page"
property string option2Text: "Base screen option"
menuBar: MenuBar {
Menu {
title: qsTr("Menu")
MenuItem
{
id: option1TextItem
text: qsTr(option1Text)
onTriggered: stackView.push("qrc:/qml/SecondPage.qml")
}
MenuItem
{
id: option2TextItem
text: qsTr(option2Text)
onTriggered: console.log("Triggered option 2")
}
}
}
StackView
{
id: stackView
anchors.fill: parent
focus: true
initialItem: FirstPage {}
}
}
FirstPage:
Rectangle {
anchors.fill: parent
Component.onCompleted: {
rootWindow.option1Text = "First Page"
rootWindow.option2Text = "First Page Option"
}
}

Related

QML, the menu icon will does not show up correctly

The following standard QML code does not work. Instead of the 3 small bar menu icon (unicode u2630), I get a rectangle with a cross inside: it does not find the character. However it finds the u25C0 left arrow (back triangle button) when required.
This is only a cosmetic glitch, as it works perfectly.
Has this anything related to the font, or with a mapping to an icon? How to solve this?
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
id: window
width: 640
height: 480
visible: true
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
}
}
(...)
For those who come here from search I will leave here the answer from a Qt.io forum
https://forum.qt.io/topic/123877/stackview-icon-on-android

How to build dynamically loading Qml pages onto main and swipe between pages?

I have a 3 Qml page like home.qml, weather.qml and currency.qml. In home.qml page I need to load (as I thought the right way) 3 page and I can use Qml Swipe with Loader to load pages. I need to swipe between pages like 1->2->3 and 3->2->1.
Also, I need show that home.qml page is the first page. I check the **doc.qt.io/qt-5/qml-qtquick-controls2-swipeview . html link but I couldn’t load my other 2 pages, so I can swipe. Where I can get the info, so I can build dynamically loading Qml pages onto main and swipe between pages.
Any help please?
UPDATED WORKING CODE:
Tested on Qt5.9.2 in QML app project.
Code is show in a simple way. Here is the code:
I create a new VPlay APP. It was only In Main.qml file. Than I add 3 page (Page1.qml, Page2.qml and Page3.qml)
In Main.qml I add below code.
import VPlayApps 1.0
import QtQuick 2.4
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.2
Page {
anchors.fill: parent
// Background
Rectangle {
y: 0; width: parent.width; height: parent.height
gradient: Gradient {
GradientStop { position: 0.00; color: “#1AD6FD” }
GradientStop { position: 1.00; color: “#1D62F0” }
}
}
SwipeView {
id: view
currentIndex: 0
anchors.fill: parent
anchors.top: parent.top
Item{
id: firstItem
Loader {
// index 0
id: pageOneLoader
source: “Page1.qml”
anchors.fill: parent
anchors.top: parent.top
}
}
Item{
id: secondItem
Loader {
// index 1
id: pageSecondLoader
source: “Page2.qml”
anchors.fill: parent
anchors.top: parent.top
}
}
Item{
id: thirdItem
Loader {
// index 2
id: pageThirdLoader
source: “Page3.qml”
anchors.fill: parent
anchors.top: parent.top
}
}
}
PageIndicator {
id: indicator
count: view.count
currentIndex: view.currentIndex
anchors.bottom: view.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
And Each page (page1, page2 etc) I add below code;
// emitting a Signal could be another option
Component.onDestruction: {
cleanup()
}
Code is show in a simple way. Here is the code:
I create a new VPlay APP. It was only In Main.qml file. Than I add 3 page (Page1.qml, Page2.qml and Page3.qml) In Main.qml I add below code.
import VPlayApps 1.0
import QtQuick 2.4
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.2
Page {
anchors.fill: parent
// Background
Rectangle {
y: 0; width: parent.width; height: parent.height
gradient: Gradient {
GradientStop { position: 0.00; color: “#1AD6FD” }
GradientStop { position: 1.00; color: “#1D62F0” }
}
}
SwipeView {
id: view
currentIndex: 0
anchors.fill: parent
anchors.top: parent.top
Item{
id: firstItem
Loader {
// index 0
id: pageOneLoader
source: “Page1.qml”
anchors.fill: parent
anchors.top: parent.top
}
}
Item{
id: secondItem
Loader {
// index 1
id: pageSecondLoader
source: “Page2.qml”
anchors.fill: parent
anchors.top: parent.top
}
}
Item{
id: thirdItem
Loader {
// index 2
id: pageThirdLoader
source: “Page3.qml”
anchors.fill: parent
anchors.top: parent.top
}
}
}
PageIndicator {
id: indicator
count: view.count
currentIndex: view.currentIndex
anchors.bottom: view.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
And Each page (page1, page2 etc) I add below code;
// emitting a Signal could be another option
Component.onDestruction: {
cleanup()
}

Qt/QML SwipeDelegate doesn't work properly on mobile devices (Android, iOS)

I'm new to Qt/QML programming and am trying to get the following example to run properly on a mobile device. When I try to "swipe right" and then tap the remove button, the "Listview-item" will not be deleted. On Desktop all works fine, but on a mobile device it doesn't work properly. Can anyone help me with my problem?
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
id: appWindow
visible: true
ListView {
id: listView
anchors.fill: parent
model: ListModel {
ListElement { name: "Swipe Delegate - Test 1" }
ListElement { name: "Swipe Delegate - Test 2" }
ListElement { name: "Swipe Delegate - Test 3" }
ListElement { name: "Swipe Delegate - Test 4" }
}
delegate: SwipeDelegate {
id: swipeDelegate
text: model.name
width: parent.width
ListView.onRemove: SequentialAnimation {
PropertyAction {
target: swipeDelegate
property: "ListView.delayRemove"
value: true
}
NumberAnimation {
target: swipeDelegate
property: "height"
to: 0
easing.type: Easing.InOutQuad
}
PropertyAction {
target: swipeDelegate;
property: "ListView.delayRemove";
value: false
}
}
swipe.right: Label {
id: deleteLabel
text: qsTr("Delete")
color: "white"
verticalAlignment: Label.AlignVCenter
padding: 12
height: parent.height
anchors.right: parent.right
SwipeDelegate.onClicked: listView.model.remove(index)
background: Rectangle {
color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
}
}
}
}
}
You can add a MouseArea with an onClicked-event inside the Rectangle. Here is the example:
background: Rectangle {
color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
MouseArea {
anchors.fill: parent
onClicked: listView.model.remove(index)
}
}

Showing a Dialog onCompleted doesn't work as expected

I want to show a Dialog onCompleted under some condition (handling this condition omitted here - a simple if clause)
main.qml:
import QtQuick 2.2
import QtQuick.Controls 1.0
ApplicationWindow
{
id: appWindow
width: 480
height: 640
visible: true
StackView
{
id: stackView
anchors.fill: parent
// Implements back key navigation
focus: true
initialItem: Item
{
width: parent.width
height: parent.height
Button { onClicked: dialog.open() }
// ...
Component.onCompleted: dialog.open()
}
}
MyDialog {id: dialog }
}
MyDialog.qml
import QtQuick 2.0
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0
Dialog
{
id: root
title: "MyDialog"
standardButtons: Qt.NoButton
ColumnLayout
{
id: column
width: parent ? parent.width : 200
Label { text: "hello world"; Layout.fillWidth: true }
}
}
When I launch my app, the screen is dimmed, and the Dialog's shade appears, as though the dialog had width == 0.
Sometimes (rarely) the dialog shows correctly.
If I comment out the Component.onCompleted line and launch the dialog using the Button, it is displayed correctly.
What am I doing wrong?
I'm using Qt 5.5 for Android
Opening the dialog doesn't work correctly if it's opened before the window has a sane geometry.
A safe option is to use the onWidthChanged signal
main.qml
import QtQuick 2.2
import QtQuick.Controls 1.0
ApplicationWindow
{
id: appWindow
width: 480
height: 640
visible: true
StackView
{
id: stackView
anchors.fill: parent
// Implements back key navigation
focus: true
initialItem: Item
{
property bool firstTime: true
width: parent.width
height: parent.height
// ...
// width may be called multiple times
onWidthChanged: if (firstTime) {firstTime = true; dialog.open()}
}
}
MyDialog {id: dialog }
}
Please, refer to official documentation about Dialog QML Type, there you can find next:
Note: do not attempt to bind the width or height of the dialog to the
width or height of its content, because Dialog already tries to size
itself to the content. If your goal is to change or eliminate the
margins, you must override contentItem. If your goal is simply to show
a window (whether modal or not), and your platform supports it, it is
simpler to use Window instead.
So, in your case, it will be better somehow set width of your inner element implicitly. Another quick solution is to add (for example) Rectangle element with given width as only one inner root element of your Dialog. Rest of elements you can place inside this Rectangle.
I'm posting another answer because it is another approach. I remembered how I implemented it on some old project. AFAIK, For now it is the best way. I would be really happy if anyone gave better solution.
You need to add one intermediary element like Timer. This timer (tm in code below) must have small interval (like 30ms) and need to be started on your desired event -- Component.onCompleted. Put your action in onTriggered of this timer.
Here is code:
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
Timer {
id: tm
interval: 30
onTriggered: dialog.open()
}
StackView {
id: stackView
anchors.fill: parent
// Implements back key navigation
focus: true
initialItem: Item {
width: parent.width
height: parent.heonTriggeredight
Button { onClicked: dialog.open() }
Component.onCompleted: tm.start()
}
}
MyDialog { id: dialog }
}

Cant get button to appear

I'm trying to make some sort of fotboll app for android. The problem i'm facing right now, is that I need to make a button in the corner of the screen, (4 different) which you move the game character with. But I've made 1 button now, for moving up, but it doesnt appear on the screen.
Main file:
import QtQuick 2.0
import QtQuick.Window 2.1
Item {
id:root
width:Screen.width
height:Screen.height-10
focus:true
Keys.onPressed: {
if(event.key===Qt.Key_Up)
{
event.accepted = true;
player.y=(player.y) - 40
}
if(event.Key === Qt.Key_Down){
event.accepted = true;
player.y = (player.y)+ 40
}
if (event.key === Qt.Key_Right)
{ event.accepted=true;
player.x=(player.x)+40
}
if (event.key === Qt.Key_Left)
{event.accepted = true;
player.x=(player.x) -40
}
}
Flickable {
width:Screen.width
height:Screen.height
contentHeight: Screen.height*2
contentWidth:Screen.width
interactive:true
boundsBehavior: Flickable.StopAtBounds
contentY: Math.min(contentHeight-height, Math.max(0, player.y-height/2))
contentX: Math.min(contentWidth-width, Math.max(0, player.x-width/2))
Image{
id: feild
anchors.fill:parent
source:"Namnlös.png"
sourceSize.height:Screen.height*2
sourceSize.width:Screen.width
}
Image {
id: player
source:"asd.png"
x:Screen.width/2
y:Screen.height/2
}
}
}
Button file:
import QtQuick 2.0
import QtQuick.Window 2.1
Rectangle {
id: simplebutton
color: "grey"
width: 100; height: 50
Text {
id: buttonLabel
anchors.centerIn: parent
text: "Up"
}
MouseArea {
id: buttonMouseArea
anchors.fill: parent
onClicked: console.log(buttonLabel.text + "clicked" )
}
}
Rectangle {
id: button
property color buttonColor: "lightblue"
property color onHoverColor: "gold"
property color borderColor: "white"
signal buttonClick()
onButtonClick: {
console.log(buttonLabel.text + " clicked" )
}
MouseArea {
onClicked: buttonClick()
hoverEnabled: true
onEntered: parent.border.color = onHoverColor
onExited: parent.border.color = borderColor
}
color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor
}
Two things:
1) You need to add your button to your layout! Since there you don't add your button into your main file, it won't appear.
2) You need to split your Button file into two separate qml file, since you can only have one "root" item per file.

Categories

Resources