ListView signals and slots for menu elements

前端 未结 1 547
既然无缘
既然无缘 2021-01-22 19:21

I\'m trying to implement some sort of custom Menu with custom elements. The ultimate goal is to create some sort of popup menu with text and icons. But during creation I faced w

1条回答
  •  闹比i
    闹比i (楼主)
    2021-01-22 19:43

    The problem with the signal is related to its declaration. Signals are always declared as a function would be: with a signature. In other words, a signal without parameters has the form

    signal ()
    

    That's also why you got the error "is not a function". Apart from that, the usage of signals/signal handlers is correct. Anyhow, reading carefully the documentation wouldn't hurt. This page covers in detail the argument.

    Coming to the other problem, you made the wrong assumption: anything that is declared inside a component is part of the children of the component itself. Here you declared a BreezeQuickMenu which has a child ListView. When you use it and add the BreezeQuickMenuItems, you add them to the same set to which the ListView belongs. In the end you have four elements in the children property. Also, by adding the ListView to itself through the model you mess up things to the point that a totally unrelated string is rendered.

    There are several ways to handle Items as model members for a view, inclusing VisualItemModel and using object Instanced as models. However, by skimming your code, it is clear that you want to define a component which adds menu items in a declarative fashion. Using children is not sufficient in this case. You also need the default property:

    An object definition can have a single default property. A default property is the property to which a value is assigned if an object is declared within another object's definition without declaring it as a value for a particular property.

    Hence you can define the default property for your BreezeQuickMenu and exploit it to obtain the desired children for your list. A common approach would be the following (code simplified):

    import QtQuick 2.4
    
    Item {
        id: root
        property BreezeQuickPalette palette: BreezeQuickPalette
        property alias currentIndex: menuList.currentIndex
    
        // default declaration  (1)
        default property alias contents: addItem.children
    
        // Item to which the inner declared meantime will belong  (2)
        Item {
            id: addItem
        }
    
        property font menuFont
        property bool menuVisible: false
    
        implicitWidth: 128
        implicitHeight: menuList.height
        ListView{
            id: menuList
            anchors.fill: parent
            model: contents                 // usage of the default property  (3)
            clip: true
            delegate: Rectangle {
                // your current delegate code
            }
        }
    }
    

    The basic idea is to exploit also property alias: basically in (1) we are saying that "all the Items declared inside BreezeQuickMenu are automatically children of addItem which is an inner declared Item (2). In this way the ListView is kept apart whereas all the BreezeQuickMenuItem are gathered together, under addItem children property. At this point, it is sufficient to use the same children property as the model (3) for the ListView and that's it.

    0 讨论(0)
提交回复
热议问题