Results 1 to 7 of 7

Thread: Getting a specific list element

  1. #1
    Join Date
    May 2017
    Posts
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Getting a specific list element

    I am new to programming but I volunteered to make a GUI for my job. I have a nice GUI going that triggers GPIO on the PI using QT Quick. There is one more feature I really want. I have a model with List Elements being displayed using pathview. I want specific details about the item in the current index. In this case its a recipe system so when you scroll through all the recipes in pathview, I want the recipe for the item that is highlighted to show up at the bottom of the screen. My problem is if index 3 is selected I don't know how to get ingredient 1, ingredient 2, etc for index 3. If I called the pathview id: view, is there some sort of view, element 3, ingredient 1 lookup I can use?

    import QtQuick 2.0

    In Recipes.qml
    ListModel {
    id: recipe
    ListElement { name: "Beef Rissotto"
    icon: "file:/Beef_Risott.jpg" }
    ListElement { name: "Southwestern Alfredo"
    icon: "file:/Southwestern_Alfredo.jpg" }
    ListElement { name: "Chef's chocolate salty balls"
    icon: "file:/Beef_Risott.jpg" }
    ListElement { name: "Other good stuff"
    icon: "file:/Southwestern_Alfredo.jpg" }

    }


    In main.qml


    Component {
    id: appDelegate
    Item {
    width: 400; height: 400; z:1;
    scale: PathView.iconScale

    Image {
    id: myIcon
    y: 0; anchors.horizontalCenter: parent.horizontalCenter
    source: icon

    }
    Text {
    anchors { top: myIcon.bottom; horizontalCenter: parent.horizontalCenter }

    text: name
    font.pixelSize: 40
    }

    MouseArea {
    anchors.fill: parent
    onClicked: view.currentIndex = index



    }
    }
    }

    Component {
    id: appHighlight
    Rectangle { width: 400; height: 400; color: "yellow" }
    }

    PathView {
    id: view
    anchors.fill: parent
    //highlight: appHighlight
    preferredHighlightBegin: 0.5
    preferredHighlightEnd: 0.5
    focus: true
    model: recipe
    delegate: appDelegate
    path: Path {
    startX: 100
    startY: 120
    PathAttribute { name: "iconScale"; value: 0.2 }
    PathLine { x: 400; y: 120; }
    PathAttribute { name: "iconScale"; value: 0.4 }
    PathLine { x: 700; y: 120;}
    PathAttribute { name: "iconScale"; value: 0.2 }

    }



    Image {
    id: image
    x: 0
    y: 0
    width: 800
    height: 480
    opacity: 1
    anchors.bottom: parent.bottom
    source: "file:/background.jpg"
    }

    Rectangle{width: parent.width; heightarent.height/2.5 ; color: "black";anchors.bottomarent.bottom;

    I would like to put the specific ingredients here

    }

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Getting a specific list element

    I think you are confusing the data you want to display with how you want to display it. Most developers would not hard-code the data into lists the way you are doing, they would define a data structure that could be stored in a disk file and updated independently of the GUI. The contents of the disk file are read in at run time and used to build the lists displayed on screen.

    Something that would work well for a simple thing like a recipe file would be XML, something like this:

    Qt Code:
    1. <?xml version="1.0" ?>
    2. <RecipeList>
    3. <Recipe name="Beef Risotto" serves="4" difficulty="moderate">
    4. <IngredientsList>
    5. <Ingredient name="Arborio rice" quantity="200" unit="gm" />
    6. <Ingredient name="Onion" quantity="1" unit="each" />
    7. <Ingredient name="Beef" quantity="300" unit="gm" />
    8. etc.
    9. </IngredientList>
    10. <Directions>
    11. Dice onion.
    12. Slice beef into 1cm cubes.
    13. Put beef broth into a saucepan and heat to simmer over medium-low heat.
    14. Melt butter in a large frying pan.
    15. Add the beef cubes and stir until browned.
    16. Remove the beef cubes.
    17. Add onions and fry until slightly browned.
    18. Add rice and stir to coat with butter.
    19. After 1 - 2 minutes, add the white wine and stir continuously until it is absorbed.
    20. Add the broth in 250 ml portions, stirring continuously after each addition until completely absorbed.
    21. When the rice is nearly cooked (it will be mostly translucent), return the beef to the pan and continue stirring until all the broth is absorbed.
    22. Stir in the cheese, adjust the seasonings, and serve immediately.
    23. </Directions>
    24. </Recipe>
    25. <Recipe name="Southwestern Alfredo" serves="6" difficulty="easy">
    26. etc.
    27. </Recipe>
    28. </RecipeList>
    To copy to clipboard, switch view to plain text mode 

    You can use the Qt Quick XmlListModel to read this from the disk and hold it in memory.

    After you read in this document, you can retrieve the names of recipes to display in your first list. Say you've named your XmlListModel with the id: recipeModel:

    Qt Code:
    1. import QtQuick 2.0
    2. import QtQuick.XmlListModel 2.0
    3.  
    4. XmlListModel {
    5. id: recipeModel
    6. source: "file://recipeList.xml"
    7. query: "/RecipeList/Recipe"
    8.  
    9. XmlRole { name: "recipeName"; query: "@name/string()" }
    10. XmlRole { name: "feeds"; query: "@serves/string()" }
    11. XmlRole { name: "easeOfPrep"; query: "@difficulty/string()" }
    12. }
    13.  
    14. ListView {
    15. id: recipesView
    16. width: 180; height: 300
    17. model: recipeModel
    18. delegate: Text { text: recipeName }
    19. }
    To copy to clipboard, switch view to plain text mode 

    In a second list view, you will use the index of the currently-selected item in the first list view to pull the names of the ingredients from the selected recipe:

    Qt Code:
    1. XmlListModel {
    2. id: ingredientsModel
    3. source: "file://recipeList.xml"
    4. query: "/RecipeList/Recipe[" + recipesView.currentIndex + "]/IngredientsList/Ingredient"
    5.  
    6. XmlRole { name: "ingredientName"; query: "@name/string()" }
    7. }
    8.  
    9. ListView {
    10. id: ingredientsView
    11. width: 180; height: 300
    12. model: ingredientsModel
    13. delegate: Text { text: ingredientName }
    14. }
    To copy to clipboard, switch view to plain text mode 

    I haven't tested this; you will probably have to play with it to make it work in your own GUI. I am not sure if you must specify the file name again for the second XmlListModel, or whether you can set its "source:" to be recipesModel. I can't find details in the QML documentation, which is pretty poor on this topic, as usual. You'll just have to try it.

    The important things are:

    1 - There is a separation between the data you want to display and the code you use to implement the GUI
    2 - The second list view is synchronized to the first using the "currentIndex" of the selected item from the first view

    Have fun.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    May 2017
    Posts
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Getting a specific list element

    Thank you so much for that very thorough answer. I will give it a try. I am struggling to find a goo tutorial. Most are hung up on the Widgets and the ones that do QML just show the basics. Any recommendations? I have tried youtube and Udemy.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Getting a specific list element

    Unfortunately, I find that the documentation on Qt Quick and QML to be sadly insufficient. What's there is either so basic as to be useless or so involved that it is impossible to understand. When I was looking at XmlListModel last night, the link takes you to a generic List model page that describes all of the various QML list models. The links on -that- page for more information on XmlListModel take you right back to the same page.

    The best I can suggest is to go to the Qt Quick Examples and tutorials and start studying things that sound like they might be useful.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    May 2017
    Posts
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Getting a specific list element

    So it turns out I am using QtRpi which uses QT5.7 cross compiled from a Linux machine to a raspberry pi. XML is not a supported module.

    I do think I found the answer in the stocqt project. In StockListView.qml they do the following.

    First they declare these variables up top


    property string currentStockId: ""
    property string currentStockName: ""


    Then they use a model.get to get the data for the active element.
    onCurrentIndexChanged: {
    if (currentItem) {
    root.currentStockId = model.get(currentIndex).stockId;
    root.currentStockName = model.get(currentIndex).name;
    }
    }

    I was playing with it and it pulls the element that is active in currentIndex. I can't try it with my stuff until Monday. My wife will kill me if I mess with this on the weekend.

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Getting a specific list element

    XML is not a supported module.
    Surprising. The Qt source code is available, so you could try building the XML module yourself if you are adventurous. If you are more adventurous, you can install a native compiler toolchain on your RPi and build it there instead of cross-compiling.

    In any case, you don't really need XML, it is just a convenient way to store hierarchical data in a readable and easily parseable way. You could also use SQLite to make a recipe database; SQLite is implemented as a single source / header pair and you simply compile it as part of your project. You don't even need the database support from Qt.

    A database might contain three tables:

    - A Recipes table, with fields for RecipeID, Name, Description, and whatever else
    - An Ingredient table, with fields for Ingredient ID, Name (this table is independent of recipe - the same ingredient can appear in more than one recipe)
    - A RecipeIngredients table linking RecipeID and IngredientID, with fields for Quantity and Unit

    From the list view containing recipes, when the user clicks a recipe line, retrieve the RecipeID by searching the Recipes table for the Name.
    From the RecipeIngredients table, retrieve all IngredientID entries where RecipeID matches
    From the Ingredients table, retrieve the Name for each matching IngredientID and display them in the ingredients list view.

    My wife will kill me if I mess with this on the weekend.
    "Honey, I'm trying to improve my skills so I can find a better job and make more money so we can have better vacations... I don't have the time to do this during the week."
    Last edited by d_stranz; 13th May 2017 at 19:06.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  7. #7
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Getting a specific list element

    in addition to d_stranz's answers:

    I would would pack the whole data in to one treemodel.
    Each recipe is a child of the root element - and it contains the name of the recipe.
    Each recipe element is a parent to ingredient elements.

    Also, remember that how data is stored and how it is in memory can vary, and it often does differ.
    I'd do what would be the easiest thing to do, for me.
    If you are very strong with XML, do it in XML, if you are strong with MySQL, you can do in MySQL, etc
    I would do it in a text file, using QSettings.
    Its easy, and you can open it with any editor and still know what the data is, and even mend it manually if needed.
    Well, I am a C++ guy, so if you have found something else that works for you better with QML, stick with it, here is just another view on things, maybe it can give you some ideas, maybe not.

    As I said, in memory I'd use a tree-model and in your recipe list I'd simply show the first level of children (the recipe names).
    For each selected recipe I'd get the list of its children and show that in a list of ingredients at the bottom.

    Since you have asked about QML documentation here is a good link if you don't know it yet:
    https://qmlbook.github.io/
    And for your case you probably would like to jump to:
    https://qmlbook.github.io/en/ch06/index.html
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

Similar Threads

  1. A list box with an specific style checkbox
    By wxShayan in forum Newbie
    Replies: 1
    Last Post: 30th December 2012, 12:53
  2. Replies: 9
    Last Post: 23rd April 2012, 13:53
  3. How to add color to the List View Element in QML?
    By harish in forum Qt Programming
    Replies: 1
    Last Post: 11th January 2012, 11:29
  4. how to access ith element of an qstring list?
    By aurora in forum Qt Programming
    Replies: 2
    Last Post: 18th October 2011, 09:37
  5. Replies: 9
    Last Post: 8th March 2011, 08:35

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.