首页 文章

在QAbstractListModel子类中为QML实现活动项功能

提问于
浏览
0

我在QML中创建了一个ListView,我希望能够使用QAbstractListModel作为QML使用的模型来实现类似活动项的东西 . 更具体地说,我正在使用通用对象模型,如this question的答案中所述 . 但是,在我的QML委托中,我有这样的事情:

Component
{
    id: itemDlgt

    Rectangle
    {
        id: rec
        width: 50
        height: 50
        color: "#645357"

        property bool itemActive: false

        AbstractItem //AbstractItem is the class that my object model uses. Its only property is a boolean value
        {
            id: s
        }

        MouseArea
        {
            anchors.fill: parent

            onClicked:
            {
                s.status = !s.status
                itemActive= s.status // using this to trigger onItemActiveChanged
                console.log(s.status)
                console.log(index)
            }
        }

        onItemActiveChanged:
        {
            if (itemActive == true)
                rec.color = "#823234"
            else
                rec.color = "#645357"
        }


    }
}

我想要做的是,ListView中只有一个项目一次保存一个真值 . 单击另一个项目后,我想将先前所选项目的AbstractItem设置为false,然后将新项目的AbstractItem设置为true .

当然,我可以使用这样的东西:

ListView 
{
    id: view
    anchors.fill: parent
    clip: true
    model: myAbstractModel
    delegate: itemDlgt
    spacing: 5 
    focus: true //using focus could allow to highlight currently selected item, 
                //by using ListView.isCurrentItem ? "blue": "red"
}

但这似乎不适用于QAbstractListModel,因为箭头键和点击项目似乎都不会突出显示当前项目 .

另外,当我使用 beginResetModel()endResetModel() 时,如果强制ListView被迫从c侧重置自己,我希望再次突出显示该项目 . 如果我正在使用Qt Documentation中描述的QAbstractListModel,我可以通过保存所选项目的索引并将其存储直到选择新项目来轻松实现 . 换句话说,这样的事情:

//somewhere in QAbstractListModel's subclass .h file
int x; // temporary storage for keeping currently selected item

//QAbstractListModel's subclass .cpp file
changeCurrentItem(int index) // function that gets called when user selects an item
{
    //...
    //Checking if x has a value, If not, I simply set the
    //needed item's value to true, and then set x to the value of index.
    //Else do the following...
    m_ItemList.at(x).setToFalse();
    m_ItemList.at(index).setToTrue();
    x = index;
}

但是当我使用它时,我正面临several issues,这就是我决定使用通用对象模型的原因,这似乎更灵活 .

最后,我希望能够在当前所选项目发生变化时向代码的c侧发送信号,这对于MouseArea来说是微不足道的,但是我知道不是使用ListView的 focus 属性来执行该操作的方法,是一个选择 .

为了缩短时间,我只想说几句:

我是否遗漏了有关QML代码的内容,这可以让我突出显示当前所选项目,同时还可以在重置ListView后保持活动状态,并且能够在c更改时向c发送信号?如果没有,有没有办法在我的通用对象模型中实现一个函数,它跟踪当前选择的项目,以便我可以突出显示它?

1 回答

  • 0

    如果使用 ListViewcurrentIndex 属性是goto方法 .

    只需通过以下方式设置代理中的颜色:

    color: index == view.currentIndex ? "blue": "red"

    并且不要忘记,为了使其工作, you 必须设置活动索引,它不能通过魔术工作,默认情况下它将为-1,因此不会突出显示任何项目:

    //in the delegate mouse area
    onClicked: view.currentIndex = index
    

    这同样适用于键盘事件,您必须告诉视图如何处理事件,因此您可以使用向上和向下键增加和减少当前索引 .

    还有另一种方法,如果要从任何视图中分离活动项功能,并在项级别拥有它,则更适用:

    property ItemType activeItem: null
    function setActiveItem(item) {
      if (activeItem) activeItem.active = false
      activeItem = item
      activeItem.active = true
    }
    

    focus属性仅指定项是否具有键盘事件焦点 .

    如果要在索引更改时发出信号,请使用 onCurrentIndexChanged

相关问题