【问题标题】:Implementing an active item function in QAbstractListModel subclass for QML在 QML 的 QAbstractListModel 子类中实现活动项功能
【发布时间】:2017-04-29 00:29:55
【问题描述】:

我已经在 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( )。如果我使用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++ qt qml


    【解决方案1】:

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

    只需通过以下方式在委托中设置颜色:

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

    别忘了,为了让这个工作,必须设置活动索引,它不能用魔法工作,默认情况下它会是-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

    【讨论】:

    • 谢谢!这正是我所需要的!
    猜你喜欢
    • 1970-01-01
    • 2014-05-07
    • 1970-01-01
    • 2015-12-31
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多