添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

Welcome to Qt Centre .

Qt Centre is a community site devoted to programming in C++ using the Qt framework . Over 90 percent of questions asked here gets answered. If you are looking for information about Qt related issue — register and post your question.

You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our community today !

If you have any problems with the registration process or your account login, please contact us .

Can you give an example of what you intend to do?
A ListView works on a single model and single delegate at any given time, but of course either can be changed during runtime, etc.
Cheers,
Thanks for the reply.
My requirement is like i am getting different models from C++ side at runtime. Similarly i have to show these data in different kind of delegates in same qml.
Basically its a list screen which has different categories.
I tried to use loader for different delegates but i am not able to access the model from loader , however if i explicitly use one , one data from model as like variables i am able to do it , but model as a whole not able to.
I have even read that loader should be avoided .
Can you please suggest what kind of a design should i prefer for this There are several options:
- you get the model data into local properties of the main delegate and then give the main delegate object to the loaded ite
- use Binding elements to bind the model data to the loaded item's properties
- make the ListView's delegate property an expression that evaluates to the wanted delegate instead of using a Loader
1.Yes active model is getting replaced by another model.Yes we are binding it to a c++ property.
2.Delegate changes for different model , different delegates are used.Some delegates, has to show only one information in field in list , some two , some more.
3.I tried the 3rd one , but whenever i am assigning from one delegate to another , it first goes and executes the first delegate and then the other one , hence i am getting reference errors, there is some context problem i think.I did not understand the first and 2nd option how to do it. If possible , please can you give a small code snippet for those 2 options.
4. I will search and let you know where i read , loader is not a good option.
5.I hope i can make you understand .
Thanks a lot for ur reply So there is no direct association between model and delegate?
You need to switch delegate even if the model stays the same?
Base on some data in the model?
In the first option you have some property in the item that gets loaded that is set to one of the object that always exist, e.g. the main delegate.
The loaded item always accesses that object's properties.
For the second option just look at the documentation of the Binding element: http://doc.qt.io/qt-5/qml-qtqml-binding.html
The target would be the Loader's "item", the property whatever it has and the value would be the "model" expression.
It is quite difficult to answer questions on such a highly abstract level, so any example would help.
Cheers,
Thank you very much for the reply.
So there is no direct association between model and delegate?
You need to switch delegate even if the model stays the same?
Base on some data in the model?
Yes there is direct association between model and delegate , for a specific model we have to show the details in a specific format.
So i have taken a specific delegate, for one model one delegate.Since we are getting the model from C++ and i see that this model contains data which is
not present in another models , so i have to make different delegates for different model , since my requirement is like that.
Can you give an example of how the binding for the delegate property looked in such a case?
Since my model is changing suppose the user has chosen some new categaory on a button press
Hence i am doing like
OnClicked{
mylistview.model=newmodel//the new model for the category
mylistview.delegate =newdelegate//the new way i have to show the data with new fields
Here in the above case i see when i assign like this it once again goes and executes the mylistview.delegate and then it goes to execute the newdelegate , hence in the previous case "mylistview.delegate" is executed and since the model is changed to the new model hence i get reference error.
In the first option you have some property in the item that gets loaded that is set to one of the object that always exist, e.g. the main delegate.
The loaded item always accesses that object's properties.
This wont be useful in my case as i have dynamic model
For the second option just look at the documentation of the Binding element: http://doc.qt.io/qt-5/qml-qtqml-binding.html
The target would be the Loader's "item", the property whatever it has and the value would be the "model" expression.
I already tried the above like below
Loader
........
property variant mymodel = model from C++
onLoaded:
Binding {
target: myloader.item
property: "mymodel "
value: mymodel
when: loader.status == Loader.Ready
but i see that the delegate is not able to access the data in this case.
however if i do something like this
inside loader
property var myalbumname = albumname //this is one role inside model
In the above case i am able to access the data in delegate but if iam trying to expose model as whole in loader i am not , i am not able to figure out where i am going wrong. So there is a property that returns the current model.
Either on the same object or on each model have a property that returns some kind of identifier.
Then in QML, you use that identifier to switch between Components for the delegate
Qt Code: Switch view
  1. ListView {
  2. model: cppObject.currentModel
  3. delegate: switch (cppObject.currentDelegate) {
  4. case "album": return albumDelegate;
  5. //....
  6. }
  7. }
  8.  
  9. Component {
  10. id: albumDelegate
  11.  
  12. Text {
  13. text: model.albumname
  14. }
  15. }
ListView {
    model: cppObject.currentModel
    delegate: switch (cppObject.currentDelegate) {
        case "album": return albumDelegate;
        //....
Component {
    id: albumDelegate
    Text {
        text: model.albumname
To copy to clipboard, switch view to plain text mode 
mylistview.model=newmodel//the new model for the category
mylistview.delegate =newdelegate//the new way i have to show the data with new fields
Here in the above case i see when i assign like this it once again goes and executes the mylistview.delegate and then it goes to execute the newdelegate , hence in the previous case "mylistview.delegate" is executed and since the model is changed to the new model hence i get reference error.
I see.
Maybe first set the delegate to undefined, then change the model, then set the delegate to the new one
but i see that the delegate is not able to access the data in this case.
however if i do something like this
inside loader
property var myalbumname = albumname //this is one role inside model
In the above case i am able to access the data in delegate but if iam trying to expose model as whole in loader i am not , i am not able to figure out where i am going wrong. You don't want to access the model inside the delegate, but as usual the current index in the model, i.e. the data at for the current item.
But that doesn't help you anyway since your delegates all need different data.
Cheers,
Thanks for the reply.
I understand from your reply that now i have to switch between the components , but as i will be assigning from one previous to the new delegate , again i will get a reference error , just to verify what you suggested i have written a small example which contains 2 models and 2 delegates and i try to assign it alternatively , but as i am doing the first assignment of model and delegate in the first mouse click i get refernce error as usual
qml: entering assigning model
qrc:/main.qml:57: ReferenceError: name is not defined
qrc:/main.qml:57: ReferenceError: name is not defined
qrc:/main.qml:57: ReferenceError: name is not defined
qrc:/main.qml:64: ReferenceError: mylistview is not defined
qml: entering assigning modeln
Also below i am posting the code i wrote , please can you suggest how to get out of these errors.
Qt Code: Switch view
  1. //////////////////////////////////////////////////////
  2.  
  3. import QtQuick 2.3
  4. import QtQuick.Window 2.2
  5.  
  6. Window {
  7. visible: true
  8.  
  9. MouseArea {
  10. anchors.fill: parent
  11. onClicked: {
  12. console.log("entering assigning model")
  13. mylistview.model=model2
  14. mylistview.delegate=comp2
  15. }
  16. }
  17.  
  18.  
  19.  
  20. ListModel{
  21. id:model1
  22. ListElement{
  23. name:"Element1"
  24. }
  25. ListElement{
  26. name:"Element2"
  27. }
  28. ListElement{
  29. name:"Element3"
  30. }
  31. }
  32.  
  33. ListModel{
  34. id:model2
  35. ListElement{
  36. fame:"Element4"
  37. }
  38. ListElement{
  39. fame:"Element5"
  40. }
  41. ListElement{
  42. fame:"Element6"
  43. }
  44. }
  45.  
  46. Component
  47. {
  48. id:comp1
  49. Row{
  50. Rectangle
  51. {
  52. width:50
  53. height:50
  54. color:"red"
  55. border.width: 2
  56. border.color: "black"
  57. Text {
  58.  
  59. text: name
  60. }
  61. MouseArea {
  62. anchors.fill: parent
  63. onClicked: {
  64. console.log("entering assigning model")
  65. mylistview.model=model2
  66. mylistview.delegate=comp2
  67. }
  68.  
  69. }
  70. }
  71. }
  72. }
  73. Component
  74. {
  75. id:comp2
  76. Row{
  77. Rectangle
  78. {
  79. width:50
  80. height:50
  81. color:"blue"
  82. border.width: 2
  83. border.color: "black"
  84. Text {
  85.  
  86. text: fame
  87. }
  88. MouseArea {
  89. anchors.fill: parent
  90. onClicked: {
  91. console.log("entering assigning model")
  92. mylistview.delegate=comp1
  93. mylistview.model=model1
  94.  
  95. }
  96.  
  97.  
  98. }
  99.  
  100. }
  101.  
  102. }
  103. }
  104. ListView
  105. {
  106. id:mylistview
  107. anchors.fill: parent
  108. model:model1
  109. delegate: comp1
  110. }
  111. }
  112.  
  113. ////////////////////////////////////
//////////////////////////////////////////////////////
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
    visible: true
    MouseArea {
        anchors.fill: parent
        onClicked: {
            console.log("entering assigning model")
            mylistview.model=model2
            mylistview.delegate=comp2
    ListModel{
        id:model1
        ListElement{
            name:"Element1"
        ListElement{
            name:"Element2"
        ListElement{
            name:"Element3"
    ListModel{
        id:model2
        ListElement{
            fame:"Element4"
        ListElement{
            fame:"Element5"
        ListElement{
            fame:"Element6"
    Component
        id:comp1
           Rectangle
            width:50
            height:50
            color:"red"
            border.width: 2
            border.color: "black"
            Text {
                text: name
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    console.log("entering assigning model")
                    mylistview.model=model2
                    mylistview.delegate=comp2
    Component
        id:comp2
           Rectangle
            width:50
            height:50
            color:"blue"
            border.width: 2
            border.color: "black"
            Text {
                text: fame
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    console.log("entering assigning model")
                    mylistview.delegate=comp1
                    mylistview.model=model1
    ListView
     id:mylistview
     anchors.fill: parent
     model:model1
     delegate: comp1
////////////////////////////////////
To copy to clipboard, switch view to plain text mode
Looks like you forgot the "assign undefined" part suggested above.
But then again, why worry about such a transient "error"
Cheers,
When i am trying to access the data of the second model from the mouse click , it is not happening , it cannot access the model data.
Can you also suggest how can i assign undefined to a delegate.
I tried something like this
mylistview.delegate = undefined
But this did not work out What does "not work out" mean?
If it can't do the assignment, you could try an "empty" delegate component, i.e. a component with just an empty Item{}
Cheers,
Thank you for the reply
I tried the above suggestions but again the reference error issue , now the mylistview itself is not available.
Below is the whole code which i tried:
Qt Code: Switch view
  1. import QtQuick 2.3
  2. import QtQuick.Window 2.2
  3.  
  4. Window {
  5. visible: true
  6.  
  7.  
  8. Component{
  9. id:emptycomp
  10. Item{}
  11.  
  12. }
  13.  
  14. ListModel{
  15. id:model1
  16. ListElement{
  17. name:"Element1"
  18. }
  19. ListElement{
  20. name:"Element2"
  21. }
  22. ListElement{
  23. name:"Element3"
  24. }
  25. }
  26.  
  27. ListModel{
  28. id:model2
  29. ListElement{
  30. fame:"Element4"
  31. }
  32. ListElement{
  33. fame:"Element5"
  34. }
  35. ListElement{
  36. fame:"Element6"
  37. }
  38. }
  39.  
  40. Component
  41. {
  42. id:comp1
  43. Row{
  44. Rectangle
  45. {
  46. width:50
  47. height:50
  48. color:"red"
  49. border.width: 2
  50. border.color: "black"
  51. Text {
  52.  
  53. text: name
  54. }
  55. MouseArea {
  56. anchors.fill: parent
  57. onClicked: {
  58. console.log("entering assigning model")
  59. mylistview.delegate=emptycomp
  60. mylistview.model=model2
  61. mylistview.delegate=comp2
  62. }
  63.  
  64. }
  65. }
  66. }
  67. }
  68. Component
  69. {
  70. id:comp2
  71. Row{
  72. Rectangle
  73. {
  74. width:50
  75. height:50
  76. color:"blue"
  77. border.width: 2
  78. border.color: "black"
  79. Text {
  80.  
  81. text: fame
  82. }
  83. MouseArea {
  84. anchors.fill: parent
  85. onClicked: {
  86. console.log("entering assigning model")
  87. mylistview.delegate=emptycomp
  88. mylistview.delegate=comp1
  89. mylistview.model=model1
  90.  
  91. }
  92.  
  93.  
  94. }
  95.  
  96. }
  97.  
  98. }
  99. }
  100. ListView
  101. {
  102. id:mylistview
  103. anchors.fill: parent
  104. model:model1
  105. delegate: comp1
  106. }
  107. }
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
    visible: true
Component{
 id:emptycomp
    Item{}
    ListModel{
        id:model1
        ListElement{
            name:"Element1"
        ListElement{
            name:"Element2"
        ListElement{
            name:"Element3"
    ListModel{
        id:model2
        ListElement{
            fame:"Element4"
        ListElement{
            fame:"Element5"
        ListElement{
            fame:"Element6"
    Component
        id:comp1
           Rectangle
            width:50
            height:50
            color:"red"
            border.width: 2
            border.color: "black"
            Text {
                text: name
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    console.log("entering assigning model")
                    mylistview.delegate=emptycomp
                    mylistview.model=model2
                    mylistview.delegate=comp2
    Component
        id:comp2
           Rectangle
            width:50
            height:50
            color:"blue"
            border.width: 2
            border.color: "black"
            Text {
                text: fame
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    console.log("entering assigning model")
                    mylistview.delegate=emptycomp
                    mylistview.delegate=comp1
                    mylistview.model=model1
    ListView
     id:mylistview
     anchors.fill: parent
     model:model1
     delegate: comp1
To copy to clipboard, switch view to plain text mode