如何在 qml 中没有 listmodel 的情况下存储嵌套 ListView 的数据并在之后检索

Posted

技术标签:

【中文标题】如何在 qml 中没有 listmodel 的情况下存储嵌套 ListView 的数据并在之后检索【英文标题】:How to store the data of a nested ListView and retrieve after , without a listmodel in qml 【发布时间】:2021-09-30 16:53:03 【问题描述】:

我有3个嵌套ListViews。第一个是月份,第二个是天,第三个是一天中的小时。它们都构造了一个日历。当我点击小时@时,有一个加载器会加载一个窗口987654322@,并在Label中设置文本。此文本可以显示在小时视图中,可以通过上面的窗口删除或编辑。不幸的是,当我滚动ListViews时,无法保存文本,代表更改而不是保留标签的上下文(我想这是正常的)。目标是能够将这些文本保存在标签中(存储数据)并在应用程序关闭和重新打开时恢复它们。 下面是 3 个ListViews 的通用代码示例:

ApplicationWindow
   id:appwindow
   ............
   Item
    id:dayView
    ...........
    ListView
       id:monthofdayCalendar
       orientation:Qt.Horizontal
       model:12
       delegate: Item
       ListView
        id:dayCalendar 
        orientation: Qt.Horizontal
        model:32
        delegate: Item
        ...............
        ListView
            id:daylistView
            orientation: Qt.Vertical
            model:24
            delegate:Item
                 id:hourItem
                 property string hourTime:hourweeklistviewLabel
                 property string notetaking:notesLabe 
                 .............
                 MouseArea
                      anchors.fill:parent
                      onClicked:
                      windowLoader.active =true
                      daylistView.currentIndex=index

                      
                   
                 Rectangle
                 Label
                   id:hourweeklistviewLabel
                 
                 Label
                   id:notesLabel                                        
                   anchors.left:hourweeklistviewLabel.right
                   anchors.leftMargin: 30
                   text:""
                 //Label
                //delegate:Item
               //ListView
               //delegate:Item
             //ListView
            //delegate:Item
           //Listview
          //Item

下面是loader的代码:

Loader 
    id:windowLoader
    focus: true
    active:false
    sourceComponent: Window
        id:inputWin
        title:"Enter Note"
        width:500
        height:300
        visible:true

        onClosing:
            windowLoader.active=false
            monthofdayCalendar.currentItem.daycalendarAlias.currentItem.dayList.currentIndex = calendarMonth.selectedDate.getDate() === new Date().getDate()
                    && calendarMonth.selectedDate.getDay() === new Date().getDay()
                    && calendarMonth.selectedDate.getMonth() === new Date().getMonth()?getHour():12


        
        TextField 
            id:title
            x:50
            y:20
            placeholderText :'Enter Note'
            text:monthofdayCalendar.currentItem.daycalendarAlias.currentItem.dayList.currentItem.notetaking.text
        
        TextField
            id:timeDate

            anchors.horizontalCenter: title.horizontalCenter
            anchors.top:title.bottom
            anchors.topMargin:10
            placeholderText :  calendarMonth.selectedDate.getDate() +"-"
                   + (calendarMonth.selectedDate.getMonth()+1)+"-"
                   + calendarMonth.selectedDate.getFullYear() + " "
                   + monthofdayCalendar.currentItem.daycalendarAlias.currentItem.dayList.currentItem.hourTime.text
                

            Button 
                 id: button
                 text: qsTr("Add Note")
                 anchors.centerIn:parent

                 onClicked: 
                       if (title.text !=="")monthofdayCalendar.currentItem.daycalendarAlias.currentItem.dayList.currentItem.notetaking.text= title.text
                       else

                    
                
            
        

最大的问题是如何保存(存储)notesLabel.text 的数据,并能够在每次关闭和重新打开应用程序时显示和恢复它。 如您所见,每个ListView 的模型不是ListModel,所以如果我是对的,我认为我不能使用这些模型来保存数据。如果我错了,请指教。 无论如何,您的帮助将不胜感激。

编辑

我已经用动态创建的ListModel 更改了整数模型。ListModels 的代码如下:

                       ListModel
                                  id:hourlistModel
                                  Component.onCompleted:
                                      for (var i = 0; i <25; i++)
                                          append(createListElement())
                                      
                                  
                                    property int h:0
                                    function createListElement()

                                        return 

                                            hour : h++
                                      
                                    
                                
                       ListModel
                            id:daylistModel
                            Component.onCompleted:
                                for (var j=0; j <= 31; j++)
                                    append(createListElement())
                                
                            
                               property int dD:0
                               function createListElement()

                                    return 

                                       day : dD++
                                      
                                    
                               
                     ListModel
                            id:monthlistModel
                            Component.onCompleted:
                                for (var k=0; k <=11; k++)
                                    append(createListElement())
                                
                            
                            property int mN:0
                               function createListElement()
                                    return 
                                       monthName : mN++
                                      
                                    
                                  

我可以存储来自LabelnotesLabel 的数据吗,现在我已经将ListViews 的模型更改为ListModels?

提前致谢。

【问题讨论】:

您说得对,您不能使用整数模型以这种方式保存数据。做你想做的事需要一个 ListModel。你有什么不想使用的原因吗? @fallerdNo,没有什么特别的原因,除了我不知道如何在我的代码中使用一个。如何形成ListElements。 【参考方案1】:

我会创建一个exposed C++ class。

使用公开的 C++ 类,您可以通过一系列选项从前端/后端传递数据

Q_Property/成员 Q_Invokable 信号/插槽

鉴于您使用的是严格的字符串,我会使用一系列公开的 QStrings 或 QStringList。

QString QStringList

要解决文件读/写问题,请使用您现在公开的 C++ 类。您可以通过标准 c++ 或 QFile system 坚持文件 I/O。

    构造函数 - 读取 .txt 文件并将数据保存到您的属性数据中。 根据需要交换数据,更新 QML 或 C++ 属性成员 解构器 - 将属性成员数据保存回文件。

简要示例代码:

someQML.qml 导入 MyExposedClass 1.0

Item 
    
    MyExposedClass 
        id: myExposedClassID
        text: myExposedClassID
    
    Text
        id: yearTextID
        text: myExposedClassID.year
    
    Text
        id: monthTextID
        text: myExposedClassID.month
    
    Text
        id: dayTextID
        text: myExposedClassID.day
    
    Button 
        id: myButtonID
        onButtonPressed 
            var finalStr = yearTextID + monthTextID + dayTextID
            // If you used a QMember of qstring lets say
            myExposedClassID.saveFile = finalStr

            // If you used a QInvokable
            myExposedClassID.saveFile_INVOK(finalStr)
        
    

myClass.h

class myClass : public QObject 
    Q_OBJECT
    // Serial Dev
    Q_PROPERTY(QString day      READ getDay WRITE setDay NOTIFY dayChanged)
    Q_PROPERTY(QString month    READ ... WRITE ... NOTIFY ...)
    Q_PROPERTY(QString year     READ ... WRITE ... NOTIFY ...)

...
    // On construction, read the text file and update the qproperty variables

    //implement getters and setters for qproperties

    // On deconstruction, write the properties to file

如果您对 MVC 和 QStrings/QStringlist 有疑问。您可能需要查看 QVariants 或 QAbstract。

我发现 QML 是一个冒险的洞。向 QML 文件添加越来越多的功能很容易。但是如果你尝试重新设计它或改变一些逻辑,它会很快毁掉 QML。将 QML 拆分为 QML 和 C++ 是实现模块化和控制的好方法。

【讨论】:

以上是关于如何在 qml 中没有 listmodel 的情况下存储嵌套 ListView 的数据并在之后检索的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个 QML 访问和控制 ListModel 的内容

类型错误:无法在嵌套列表视图中读取 null 的属性“newdaycalendar”,其中 listmodel 动态创建了 qml

使用 PyQt 将项目动态设置为 QML ListModel

QML使用Sqlite数据库存储ListModel数据

QML程序实现动态切换多语言(ListModel/ListElement中的文本的多语言处理)

QML程序实现动态切换多语言(ListModel/ListElement中的文本的多语言处理)