ListView的信号和菜单元素插槽 [英] ListView signals and slots for menu elements

查看:186
本文介绍了ListView的信号和菜单元素插槽的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现某种自定义菜单的自定义元素。最终的目标是要建立某种形式的文字和图标,弹出菜单。不过,在创建过程中我遇到一些问题。我可以显示2主要问题:


  1. 有标题为一个陌生的菜单元素世界,你好在第一位置(看起来像它的阅读应用程序窗口标题):

<醇开始=2>
  • 从不时我得到这样的错误 QRC:/BreezeQuickMenu.qml:45:类型错误:Property对象QQuickListView(0x1120830)的点击不是一个函数

  • 下面是我的实际code:

    main.qml

     进口QtQuick 2.2
    进口QtQuick.Controls 1.1
    进口QtQuick.Window 2.2ApplicationWindow {
        标题:QSTR(Hello World的)
        宽度:Screen.width
        高度:Screen.height
        可见:真
        ID:赢
        颜色:brPalette.normalBackground
    BreezeQuickMenu {
        ID:brMenu
        X:490
        Y:199
        宽度:128
        身高:256
        调色板:brPalette
        menuFont.pointSize:16
        BreezeQuickMenuItem {
            标题:项目1
            onClicked:mbox.show()
        }
        BreezeQuickMenuItem {
            标题:项目2
        }
        BreezeQuickMenuItem {
            标题:第3项
        }
      }
    }

    BreezeQuickMenu.qml

     进口QtQuick 2.4项{
        ID:根
        物业BreezeQuickPalette调色板:BreezeQuickPalette
        属性别名CURRENTINDEX:menuList.currentIndex
        物业字体menuFont
        物业布尔menuVisible:假的
        implicitWidth:128
        implicitHeight:menuList.height
        列表显示{
            ID:菜单列表
            anchors.fill:父
            型号:root.children
            片段:真
            代表:组件{
                ID:菜单项
                长方形 {
                    ID:MenuElement的
                    物业布尔isCurrentItem:ListView.isCurrentItem
                    锚{
                        左:parent.left
                        右:parent.right
                    }
                    颜色:palette.normalBackground
                    高度:menuText.font.pixelSize * 1.2
                    文字{
                        ID:menuText
                        anchors.fill:父
                        文本:标题
                        颜色:palette.normalText
                        字体:menuFont
                    }
                    鼠标区域{
                        anchors.fill:父
                        hoverEnabled:真
                        onClicked:{
                            menuList.currentIndex =指数
                            menuList.model [指数] .clicked()
                        }
                    }
                }
            }
        }
    }

    BreezeQuickMenuItem.qml

     进口QtQuick 2.4项{
        ID:根
        属性字符串标题:菜单元素
        点击信号
    }

    正如你可以看到我试图实现菜单列表,并用自己的信号菜单项。我有2个问题:


    • 我怎样才能正确地摆脱使用父元素的title属性,因为我需要阅读儿童的title属性


    • 什么是在菜单元素使用信号和槽,以避免上述错误的正确的做法?


    请帮我明白了。整个项目可以在这里拉:

    混帐混帐克隆://git.$c$c.sf.net/p/breezequick/$c$c breezequick- code


    解决方案

    信号问题与它的声明。信号始终声明为一个功能是:用签名。换句话说,一个信号不带参数的形式

     信号u signal_name&GT;()

    这也是为什么你得到了错误不是一个函数。除此之外,信号/信号处理程序的使用是正确的。总之,阅​​读仔细的文档不会受到伤害。 本页面详细覆盖的说法。

    来到另一个问题,你做出了错误的假设:任何的一个组件内声明的的的儿童的部分组件本身。在这里,你声明的 BreezeQuickMenu 具有子的ListView 。当你使用它,并添加 BreezeQuickMenuItem S,将它们添加到的相同的设置该的ListView 所属。最后,你必须的的在子元素属性。此外,通过在添加的ListView 来的本身的模型你陷入困境的事情了指向一个完全无关的字符串被渲染。

    有几种方法可以处理项目作为视图模型成员,inclusing的 visualItemModel 并使用的对象实例化作为模型的。然而,撇您code,很显然,要定义它增加了一个声明的方式菜单项的组成部分。使用孩子是不是在这种情况下,就足够了。您还需要在默认属性:


      

    这是对象定义可以有一个单一的默认属性。默认属性为的属性。它如果一个对象是另一个对象的定义中声明​​的值赋给没有宣布它为值的特定属性。


    因此​​,你可以定义默认属性的 BreezeQuickMenu 并利用它来获得所需的孩子为您的列表。一种常见的方法是以下(code简体):

     进口QtQuick 2.4项{
        ID:根
        物业BreezeQuickPalette调色板:BreezeQuickPalette
        属性别名CURRENTINDEX:menuList.currentIndex    //默认的声明(1)
        默认属性别名内容:addItem.children    //项到其中内声明同时将属于(2)
        项{
            ID:的addItem
        }    物业字体menuFont
        物业布尔menuVisible:假的    implicitWidth:128
        implicitHeight:menuList.height
        列表显示{
            ID:菜单列表
            anchors.fill:父
            型号://内容的默认属性的使用(3)
            片段:真
            代表:矩形{
                //您当前的委托code
            }
        }
    }

    的基本思想是还利用属性别名 :基本上都在(1)我们说,所有的项目在<$ C $宣布ş C> BreezeQuickMenu 将自动孩子的addItem >这是一个内声明的项目(2),这样的的ListView 保持分开,而所有的 BreezeQuickMenuItem 聚集在一起,在的addItem 孩子属性。在这一点上,它是足够使用相同的孩子属性作为模式(3)为的ListView ,这就是吧。

    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 with some issues. I can show 2 primary problems:

    1. There is a strange menu element with title Hello world at the first position (looks like it's read title of application window):

    1. From time to time I'm getting errors like qrc:/BreezeQuickMenu.qml:45: TypeError: Property 'clicked' of object QQuickListView(0x1120830) is not a function

    Here is my actual code:

    main.qml

    import QtQuick 2.2
    import QtQuick.Controls 1.1
    import QtQuick.Window 2.2
    
    ApplicationWindow {
        title: qsTr("Hello World")
        width: Screen.width
        height: Screen.height
        visible: true
        id: win
        color: brPalette.normalBackground
    BreezeQuickMenu{
        id: brMenu
        x: 490
        y: 199
        width: 128
        height: 256
        palette: brPalette
        menuFont.pointSize: 16
        BreezeQuickMenuItem{
            title: "Item 1"
            onClicked: mbox.show()
        }
        BreezeQuickMenuItem{
            title: "Item 2"
        }
        BreezeQuickMenuItem{
            title: "Item 3"
        }
      }
    }
    

    BreezeQuickMenu.qml

    import QtQuick 2.4
    
    Item {
        id: root
        property BreezeQuickPalette palette: BreezeQuickPalette
        property alias currentIndex: menuList.currentIndex
        property font menuFont
        property bool menuVisible: false
        implicitWidth: 128
        implicitHeight: menuList.height
        ListView{
            id: menuList
            anchors.fill: parent
            model: root.children
            clip: true
            delegate: Component {
                id: menuItem
                Rectangle {
                    id: menuElement
                    property bool isCurrentItem: ListView.isCurrentItem
                    anchors {
                        left: parent.left
                        right: parent.right
                    }
                    color: palette.normalBackground
                    height: menuText.font.pixelSize*1.2
                    Text {
                        id: menuText
                        anchors.fill: parent
                        text: title
                        color: palette.normalText
                        font: menuFont
                    }
                    MouseArea {
                        anchors.fill: parent
                        hoverEnabled: true
                        onClicked: {
                            menuList.currentIndex = index
                            menuList.model[index].clicked()
                        }
                    }
                }
            }
        }
    }
    

    BreezeQuickMenuItem.qml

    import QtQuick 2.4
    
    Item {
        id: root
        property string title: "Menu Element"
        signal clicked
    }
    

    As you can see I'm trying to implement menu list and menu items with their own signals. I have 2 questions:

    • how can I properly get rid of using title property of parent element, since I need to read title property of childrens

    • what is the correct approach of using signals and slots in menu elements to avoid above error?

    Please help me to understand. Full project can be pulled here:

    git clone git://git.code.sf.net/p/breezequick/code breezequick-code

    解决方案

    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 <signal_name>()
    

    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.

    这篇关于ListView的信号和菜单元素插槽的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆