December 15, 2010

kyleplattner kyleplattner
Lab Rat
242 posts

[Solved] QML Back Button with JavaScript or ListModel?

Page  
1

This seems like it should be simple but I haven’t been able to get it done yet. I have a back button that shows up on every page except for the home page and I just want it to store the name of the last page visited and then navigate there when the user taps the back button. I have been using page loaders to navigate:

Main.qml

  1. import Qt 4.7
  2.  
  3. Rectangle {
  4.     width: 640
  5.     height: 480
  6.  
  7.  
  8.     function changePage(newPage)
  9.     {
  10.         pageLoader.source = newPage;
  11.         console.log(newPage)
  12.     }
  13.  
  14.     Loader {
  15.         id: pageLoader
  16.         z: 1
  17.         source: "1.qml"
  18.     }
  19.  
  20.     Connections {
  21.         target: pageLoader.item
  22.         onPageRequested: changePage(page)
  23.     }
  24. }

And then in each page I use:

  1.  signal pageRequested(string page)
  2.  
  3.     MouseArea {
  4.        ....
  5.         onClicked: pageRequested("2.qml")

to navigate around my pages. Obviously the 2.qml gets replaced for whatever page I am going to.

Any help would be appreciated.

Thanks,

Kyle

17 replies

December 16, 2010

xsacha xsacha
Lab Rat
517 posts

Well I think you need some sort of list to map the qml files to numbers (1,2,…).
Then have a list that stores history. Every time there is a page change, append the new index.
Then when they press back, go to last element in history and delete last one too ( put it in forward history if you want).

You can use ListModel or similar in qml or implement in c++ if you’re more comfortable.

 Signature 

- Sacha

December 16, 2010

kyleplattner kyleplattner
Lab Rat
242 posts

I agree with the concept, I am just not sure how to make, store, and edit the list you referenced.

December 16, 2010

xsacha xsacha
Lab Rat
517 posts

Try using a ListModel with elements ‘index’ and ‘filename’. You can use model.get(index).filename to map.

 Signature 

- Sacha

December 17, 2010

kyleplattner kyleplattner
Lab Rat
242 posts

I am trying to tackle this back button. This is how I began but I don’t think this is the right direction. Your feedback would be appreciated:

  1. import Qt 4.7
  2.  
  3. Rectangle {
  4.     width: 640
  5.     height: 480
  6.  
  7.  
  8.     function changePage(newPage)
  9.     {
  10.         pageLoader.source = newPage;
  11.  
  12.         newPage = backbuttonmap.get(index).filename;
  13.  
  14.         //Used for logging a page change, creates a verbose console window
  15.         //console.log(newPage)
  16.     }
  17.  
  18.     ListView {
  19.          model: BackButtonModel { id: backbuttonmap }
  20.  
  21.  
  22.     Loader {
  23.         id: pageLoader
  24.         z: 1
  25.         source: "1.qml"
  26.     }
  27.  
  28.     Connections {
  29.         target: pageLoader.item
  30.         onPageRequested: changePage(page)
  31.     }
  32. }
  33. }

My model:

  1. import Qt 4.7
  2.  
  3. ListModel {
  4.     ListElement {
  5.         index: 1
  6.         filename: "1.qml"
  7.     }
  8.     ListElement {
  9.         index: 2
  10.         filename: "2.qml"
  11.     }
  12.     ListElement {
  13.         index: 3
  14.         filename: "3.qml"
  15.     }
  16.     ListElement {
  17.         index: 4
  18.         filename: "4.qml"
  19.     }
  20.     ListElement {
  21.         index: 5
  22.         filename: "5.qml"
  23.     }
  24.     ListElement {
  25.         index: 6
  26.         filename: "6.qml"
  27.     }
  28.     ListElement {
  29.         index: 7
  30.         filename: "7.qml"
  31.     }
  32.     ListElement {
  33.         index: 8
  34.         filename: "8.qml"
  35.     }
  36.     ListElement {
  37.         index: 9
  38.         filename: "9.qml"
  39.     }
  40.     ListElement {
  41.         index: 10
  42.         filename: "10.qml"
  43.     }
  44.  
  45. }

And here is an example page:

  1. import Qt 4.7
  2.  
  3. Rectangle {
  4.     id: screen
  5.     width: 640
  6.     height: 480
  7.     color: "#086421"
  8.     signal pageRequested(string page)
  9.  
  10.     Rectangle {
  11.         id: rectangle1
  12.         x: 1
  13.         y: 0
  14.         width: 557
  15.         height: 95
  16.         gradient: Gradient {
  17.             GradientStop {
  18.                 position: 0
  19.                 color: "#b36c67"
  20.             }
  21.  
  22.             GradientStop {
  23.                 position: 0.21
  24.                 color: "#661d17"
  25.             }
  26.         }
  27.         border.width: 0
  28.         border.color: "#086421"
  29.  
  30.  
  31.         MenuTitle {
  32.             id: menutitle1
  33.             x: 0
  34.             y: 0
  35.             title: "Sound Settings"
  36.         }
  37.     }
  38.  
  39.     TabMenu {
  40.         id: tabmenu1
  41.         x: 0
  42.         y: 48
  43.         state: "State2"
  44.         onPageRequested: screen.pageRequested(page)
  45.     }
  46.  
  47.     SetupBars {
  48.         id: setupbars1
  49.         x: 558
  50.         y: 0
  51.     }
  52. }

December 17, 2010

kyleplattner kyleplattner
Lab Rat
242 posts

I tried implementing with JavaScript but I couldn’t get it to work. Any ideas would be appreciated.

  1.         var count = 0;
  2.         var stack = [];
  3.         var lastpage;
  4.  
  5. function changePage(newPage)
  6.     {
  7.  
  8.  
  9.         pageLoader.source = newPage;
  10.         stack.push(newPage);
  11.         count = count + 1;
  12.  
  13.  
  14.     }
  15.  
  16. function lastPage()
  17. {
  18.  
  19.  
  20.   lastpage = stack.pop(count);
  21.  
  22.  
  23. }

For my back button the code is:

  1. MouseArea {
  2.         id: mouse_area_back
  3.         x: 0
  4.         y: 381
  5.         width: 82
  6.         height: 99
  7.         onClicked: {
  8.             console.log(PageChange);
  9.             pageRequested(PageChange.lastpage);
  10.         }
  11.         }

and my main page:

  1. import Qt 4.7
  2. import "pageChanger.js" as PageChange
  3.  
  4. Rectangle {
  5.     width: 640
  6.     height: 480
  7.  
  8. function changePage(newPage) { PageChange.changePage(newPage) }
  9.  
  10.     Loader {
  11.         id: pageLoader
  12.         z: 1
  13.         source: "1.qml"
  14.     }
  15.  
  16.     Connections {
  17.         target: pageLoader.item
  18.         onPageRequested: changePage(page)
  19.     }
  20. }

December 17, 2010

xsacha xsacha
Lab Rat
517 posts

You’re almost there (with the first one you had).
Don’t worry about the javascript, you can do it in the QML (which really is javascript anyway).

The only thing you’re missing is the page stack. Where is the page variable? And why is it a string? If you are putting the filename (eg. 1.qml) then you don’t need the model.

 Signature 

- Sacha

December 18, 2010

kyleplattner kyleplattner
Lab Rat
242 posts

You will have to excuse my ignorance again but how do I implement a page stack in qml?

December 18, 2010

xsacha xsacha
Lab Rat
517 posts

Like you were trying to do in the javascript.
Make a List with previous pages you have accessed.

I don’t think you are showing all the code? When you change page (purposefully), you need to append that page to the ‘stack’ — your history (like the javascript code does).
Then, when you use the back button, simply change to the last item on your page stack. Then remove that item.

 Signature 

- Sacha

December 18, 2010

kyleplattner kyleplattner
Lab Rat
242 posts

I like the concept but I am weak on the qml code.

December 18, 2010

xsacha xsacha
Lab Rat
517 posts

I’m weak on interpreted code, more a C++ guy, but QML seems the same as Javascript (at least syntax-wise).

If you can provide me with a minimal code base that needs this ‘back button’ functionality, I can add it on for you. No need to give me all the pages, just two or three will do.

 Signature 

- Sacha

December 18, 2010

kyleplattner kyleplattner
Lab Rat
242 posts

These are my pages as they stand, javascript still there from attempt 1.

My Main.qml:

  1. import Qt 4.7
  2. import "pageChanger.js" as PageChange
  3.  
  4. Rectangle {
  5.     width: 640
  6.     height: 480
  7.  
  8. function changePage(newPage) { PageChange.changePage(newPage) }
  9.  
  10.     Loader {
  11.         id: pageLoader
  12.         z: 1
  13.         source: "1.qml"
  14.     }
  15.  
  16.     Connections {
  17.         target: pageLoader.item
  18.         onPageRequested: changePage(page)
  19.     }
  20. }

PageChanger.js

  1.         var count = 0;
  2.         var stack = ["1.qml"];
  3.         var visited;
  4.  
  5. function changePage(newPage)
  6.     {
  7.  
  8.  
  9.         pageLoader.source = newPage;
  10.         stack.push(pageLoader.source);
  11.         count = count + 1;
  12.         console.log(count)
  13.  
  14.     }
  15.  
  16. function lastPage()
  17. {
  18.  
  19.     console.log("in function")
  20.     console.log(stack);
  21. //    stack.pop();
  22.     stack.pop();
  23.     console.log(stack);
  24.     pageRequested(stack);
  25.  
  26.  
  27. }

A Sample Page:

  1. import Qt 4.7
  2.  
  3. Rectangle {
  4.     id: screen
  5.     width: 640
  6.     height: 480
  7.     color: "#086421"
  8.     signal pageRequested(string page)
  9.  
  10.     Rectangle {
  11.         id: rectangle1
  12.         x: 1
  13.         y: 0
  14.         width: 557
  15.         height: 95
  16.         gradient: Gradient {
  17.             GradientStop {
  18.                 position: 0
  19.                 color: "#b36c67"
  20.             }
  21.  
  22.             GradientStop {
  23.                 position: 0.21
  24.                 color: "#661d17"
  25.             }
  26.         }
  27.         border.width: 0
  28.         border.color: "#086421"
  29.  
  30.  
  31.         MenuTitle {
  32.             id: menutitle1
  33.             x: 0
  34.             y: 0
  35.             title: "Screen Brightness"
  36.         }
  37.     }
  38.  
  39.     TabMenu {
  40.         id: tabmenu1
  41.         x: 0
  42.         y: 48
  43.         state: "State2"
  44.         onPageRequested: screen.pageRequested(page)
  45.     }
  46.  
  47.     SetupBars {
  48.         id: setupbars1
  49.         x: 558
  50.         y: 0
  51.     }
  52. }

Setup Bars code:

  1. import Qt 4.7
  2. import "pageChanger.js" as PageChange
  3.  
  4. Rectangle {
  5.     width: 82
  6.     height: 480
  7.  
  8.  
  9.     SetupBlack {
  10.         id: setupblack1
  11.         x: 1
  12.         y: 383
  13.     }
  14.  
  15.     SetupBlack {
  16.         id: setupblack2
  17.         x: 1
  18.         y: 287
  19.     }
  20.  
  21.     SetupBlack {
  22.         id: setupblack3
  23.         x: 1
  24.         y: 191
  25.     }
  26.  
  27.     SetupBlack {
  28.         id: setupblack4
  29.         x: 1
  30.         y: 95
  31.         smooth: true //test
  32.     }
  33.  
  34.     SetupBlack {
  35.         id: setupblack5
  36.         x: 1
  37.         y: -1
  38.     }
  39.  
  40.     Text {
  41.         id: text1
  42.         x: 15
  43.         y: 36
  44.         width: 80
  45.         height: 20
  46.         color: "#ffffff"
  47.         text: "Home"
  48.         font.pixelSize: 19
  49.         font.family: "Arial"
  50.         font.bold: true
  51.     }
  52.  
  53.     Image {
  54.         id: image1
  55.         x: 5
  56.         y: 395
  57.         width: 73
  58.         height: 50
  59.         source: "Images/back.png"
  60.     }
  61.  
  62.     Text {
  63.         id: text2
  64.         x: 18
  65.         y: 440
  66.         width: 80
  67.         height: 20
  68.         color: "#ffffff"
  69.         text: "Back"
  70.         font.bold: true
  71.         font.family: "Arial"
  72.         font.pixelSize: 19
  73.     }
  74.  
  75.     MouseArea {
  76.         id: mouse_area1
  77.         x: 0
  78.         y: -2
  79.         width: 82
  80.         height: 97
  81.         onClicked: pageRequested("1.qml")
  82.     }
  83.  
  84.     MouseArea {
  85.         id: mouse_area_back
  86.         x: 0
  87.         y: 381
  88.         width: 82
  89.         height: 99
  90.         onClicked: PageChange.lastPage();
  91.         }
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98. }

December 18, 2010

xsacha xsacha
Lab Rat
517 posts

One of the more important parts is ‘TabMenu’. I guess it has all the pages on it?
I will try to implement some buttons there.

 Signature 

- Sacha

December 18, 2010

kyleplattner kyleplattner
Lab Rat
242 posts

I really had to cut that up to get it to fit within the 6000 character limit but hopefully the bulk of what matters is there.

December 18, 2010

xsacha xsacha
Lab Rat
517 posts

It’s alright, I don’t need the TabMenu. I just made some buttons. So deleted that huge post :)

I have finished the back button. Here it is:

Main.qml

  1. iimport QtQuick 1.0
  2. Rectangle {
  3.     width: 640; height: 480
  4.     ListModel {
  5.         id: pageModel
  6.         function pageRequested(page)
  7.         {
  8.             append({"page": pageLoader.source})
  9.             pageLoader.source = page
  10.         }
  11.         function pageLast()
  12.         {
  13.             pageLoader.source = get(count - 1).page
  14.             remove(count - 1)
  15.         }
  16.     }
  17.     Loader {
  18.         id: pageLoader
  19.         anchors.left: parent.left
  20.         source: "home.qml"
  21.     }
  22.     SetupBars {
  23.         anchors.right: parent.right
  24.         width: 80
  25.     }
  26. }

PageButton.qml

  1. import QtQuick 1.0
  2.  
  3. Rectangle {
  4.     property alias text: status.text
  5.     property string file
  6.     width: 100; height: 30
  7.     border.width: 3
  8.     border.color: "#086421"
  9.     Text { id: status; anchors.centerIn: parent }
  10.     MouseArea { anchors.fill: parent; onClicked: pageModel.pageRequested(file) }
  11. }

Home.qml

  1. import QtQuick 1.0
  2.  
  3. Rectangle {
  4.     id: screen
  5.     width: 560; height: 480
  6.     color: "#A834F1"
  7.     Text {
  8.         text: "Welcome Home!"
  9.         anchors.centerIn: parent
  10.     }
  11.     Rectangle {
  12.         id: rectangle1
  13.         width: parent.width
  14.         height: 95
  15.         gradient: Gradient {
  16.             GradientStop { position: 0; color: "#b36c67" }
  17.             GradientStop { position: 0.21; color: "#661d17" }
  18.         }
  19.         PageButton {
  20.             x: 50; y: 50
  21.             text: "Bluetooth"
  22.             file: "1.qml"
  23.         }
  24.         PageButton {
  25.             x: 200; y: 50
  26.             text: "Screen Brightness"
  27.             file: "2.qml"
  28.         }
  29.     }
  30. }

1.qml

  1. import QtQuick 1.0
  2.  
  3. Rectangle {
  4.     id: screen
  5.     width: 560; height: 480
  6.     color: "#086421"
  7.     Text {
  8.         text: "Bluetooth!"
  9.         anchors.centerIn: parent
  10.     }
  11.     Rectangle {
  12.         id: rectangle1
  13.         width: parent.width
  14.         height: 95
  15.         gradient: Gradient {
  16.             GradientStop { position: 0; color: "#b36c67" }
  17.             GradientStop { position: 0.21; color: "#661d17" }
  18.         }
  19.         PageButton {
  20.             x: 50; y: 50
  21.             text: "Screen Brightness"
  22.             file: "2.qml"
  23.         }
  24.     }
  25. }

2.qml

  1. import QtQuick 1.0
  2.  
  3. Rectangle {
  4.     id: screen
  5.     width: 560; height: 480
  6.     color: "#9864F1"
  7.     Text {
  8.         text: "Screen Brightness"
  9.         anchors.centerIn: parent
  10.     }
  11.     Rectangle {
  12.         id: rectangle1
  13.         width: parent.width
  14.         height: 95
  15.         gradient: Gradient {
  16.             GradientStop { position: 0; color: "#b36c67" }
  17.             GradientStop { position: 0.21; color: "#661d17" }
  18.         }
  19.         PageButton {
  20.             x: 50; y: 50
  21.             text: "Bluetooth"
  22.             file: "1.qml"
  23.         }
  24.     }
  25. }

SetupBars.qml

  1. import QtQuick 1.0
  2.  
  3. Rectangle {
  4.     id: screen
  5.     width: 80; height: 480
  6.     color: "black"
  7.     Text {
  8.         id: text1
  9.         x: 15; y: 36
  10.         width: 80; height: 20
  11.         color: "white"
  12.         text: "Home"
  13.         font.pixelSize: 19
  14.         font.family: "Arial"
  15.         font.bold: true
  16.         MouseArea {
  17.             anchors.fill:  parent
  18.             onClicked: pageModel.pageRequested("home.qml")
  19.         }
  20.     }
  21.     Item {
  22.         anchors.bottom: parent.bottom;
  23.         width: 80; height: 50
  24.         visible: pageModel.count > 0
  25.         Image {
  26.             anchors.left: parent.left
  27.             source: "Images/back.png"
  28.         }
  29.         Text {
  30.             anchors.right: parent.right
  31.             color: "white"
  32.             text: "Back"
  33.             font.bold: true
  34.             font.family: "Arial"
  35.             font.pixelSize: 19
  36.         }
  37.         MouseArea {
  38.             anchors.fill: parent
  39.             onClicked: pageModel.pageLast();
  40.         }
  41.     }
  42. }

 Signature 

- Sacha

December 18, 2010

kyleplattner kyleplattner
Lab Rat
242 posts

Thanks so much for your help.

Page  
1

  ‹‹ Java and Qt Quick?      File Handling ››

You must log in to post a reply. Not a member yet? Register here!