ListView信号和菜单元素的插槽 [英] ListView signals and slots for menu elements
问题描述
我正在尝试使用自定义元素实现某种自定义菜单。最终的目标是创建一些包含文本和图标的弹出式菜单。但在创作过程中,我遇到了一些问题。我可以显示2个主要问题:
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:
- 有一个奇怪的菜单元素,标题为
Hello world
在第一个位置(看起来像是应用程序窗口的标题):
- There is a strange menu element with title
Hello world
at the first position (looks like it's read title of application window):
- 我收到错误,如
qrc:/BreezeQuickMenu.qml:45:TypeError:属性点击的对象QQuickListView(0x1120830)不是一个函数
- From time to time I'm getting errors like
qrc:/BreezeQuickMenu.qml:45: TypeError: Property 'clicked' of object QQuickListView(0x1120830) is not a function
这是我的实际代码:
main.qml p>
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:
-
如何正确摆脱使用父元素的title属性,因为我需要阅读标题
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.
出于其他问题,您做出了错误的假设:在组件中声明的内容是 c $ c>组件本身。在这里,你宣布了一个 BreezeQuickMenu
,它有一个孩子 ListView
。当您使用它并添加 BreezeQuickMenuItem
时,您将它们添加到 ListView
属于。最后,您在 children
属性中有四个元素。此外,通过模型
将 ListView
添加到本身,您会将事情指出一个完全不相关的字符串被渲染。
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 BreezeQuickMenuItem
s, 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.
有几种方法来处理项目
作为视图的模型成员,包含 VisualItemModel
并使用对象实例化作为模型。但是,通过剔除您的代码,很明显,您想定义一个以声明方式添加菜单项的组件。在这种情况下,使用 children
是不够的。您还需要默认值
属性:
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.
因此,您可以为 BreezeQuickMenu
定义默认
属性,并利用它为您的列表获取所需的儿童
。一个常见的方法将是以下(代码简化):
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
}
}
}
基本ID ea还要利用财产别名
:基本上在(1)我们说在$ code> BreezeQuickMenu中声明的所有项目
code>自动儿童
addItem
这是一个内部声明的项目
(2)。以这种方式,
ListView
保持分开,而所有 BreezeQuickMenuItem
都集合在 addItem下
children
属性。在这一点上,使用相同的 children
属性作为模型
(3) ListView
就是这样。
The basic idea is to exploit also property alias
: basically in (1) we are saying that "all the Item
s 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屋!