QML 中的类似菜单栏的行为
Posted
技术标签:
【中文标题】QML 中的类似菜单栏的行为【英文标题】:MenuBar like behaviour in QML 【发布时间】:2016-08-04 05:04:54 【问题描述】:我希望在单击矩形时具有类似菜单栏的行为。每当单击矩形时,模型就会更新并显示ListView
。我希望这个ListView
在点击另一个Rectangle
时消失,并且每次点击都不应该附加listmodel。这是我的示例代码。
Card.qml
Rectangle
id: card
width: 50
height: 100
color: "pink"
Item
id: rec
width: 50
anchors.bottom: parent.top
ListModel
id: menuListModel
Component
id: delegate
Rectangle
width: 50
height: 20
color: "blue"
Text
anchors.fill: parent
anchors.centerIn: parent
text: commandText
ListView
anchors.fill: parent
model:menuListModel
delegate: delegate
interactive: false
MouseArea
anchors.fill: parent
onClicked:
rec.height += 40;
menuListModel.append("commandText" : "Act");
menuListModel.append("commandText" : "Set");
main.qml
Item
width: 120
height: 200
Row
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
spacing: 10
Card
id: card1
Card
id: card2
我还想在单击菜单按钮时调用某些功能,即Act
和Set
。
编辑
点击卡片(此处为矩形)时,会使用适当的标志调用以下函数。
property int command_activate: 0x0001
property int command_summon: 0x0002
property int command_spsummon: 0x0004
property int command_mset: 0x0008
property int command_sset: 0x0010
property int command_repos: 0x0020
property int command_attack: 0x0040
property int command_list: 0x0080
function showMenu(flag)
if(flag & command_activate)
rec.height += 15;
menuListModel.append("commandText" : "Activate");
if(flag & command_summon)
rec.height += 15;
menuListModel.append("commandText" : "Normal Summon");
if(flag & command_spsummon)
rec.height += 15;
menuListModel.append("commandText" : "Special Summon");
if(flag & command_mset)
rec.height += 15;
menuListModel.append("commandText" : "Set");
if(flag & command_sset)
rec.height += 15;
menuListModel.append("commandText" : "Set");
if(flag & command_repos)
if(position & pos_facedown)
rec.height += 15;
menuListModel.append("commandText" : "Flip Summon");
else if(position & pos_attack)
rec.height += 15;
menuListModel.append("commandText" : "To Defense");
else
rec.height += 15;
menuListModel.append("commandText" : "To Attack");
if(flag & command_attack)
rec.height += 15;
menuListModel.append("commandText" : "Attack");
if(flag & command_list)
rec.height += 15;
menuListModel.append("commandText" : "View");
因此,简而言之,当点击卡片时,必须根据卡片顶部的flag
显示菜单。
【问题讨论】:
【参考方案1】:您的代码有几个问题。
您不能将您的delegate
命名为“代表”。当你这样做时,ListView
使用它自己的委托属性来设置自己,导致没有任何事情发生。
另外,你为什么不静态填充你的ListView
,然后使用visible
属性来切换是否显示它?如果您希望它在单击另一个Card
时消失,您可能必须使用focus
属性。
确实,将焦点设置为 true 将重置焦点范围内所有其他项目的焦点。这样的事情可能会起作用:
Rectangle
id: card
...
property alias model: list.model
Component
id: mydelegate
Rectangle
width: 50
height: 20
...
ListView
id: list
visible: card.activeFocus
anchors.bottom: parent.top
width: card.width
delegate: mydelegate
interactive: false
height: childrenRect.height
MouseArea
anchors.fill: parent
onClicked:
card.focus = !card.focus
至于调用函数,可以在ListModel
中直接添加要调用的函数名。在您的委托中添加MouseArea
,并在单击时发送信号。然后,您只需调用匹配的插槽(同意,this[slot]()
语法有点 hacky)。
在 Card.qml 中
Rectangle
id: card
...
property alias model: list.model
signal itemClicked(string slot)
Component
id: mydelegate
Rectangle
...
MouseArea
anchors.fill: parent
onClicked:
if(model.slot)
itemClicked(slot)
...
在 main.qml
...
Card
model: ListModel
ListElementcommandText: "Act"; slot: "act"
ListElementcommandText: "Set"; slot: "set"
function act()
print("act triggered")
function set()
print("set trigggered")
onItemClicked: this[slot]()
...
【讨论】:
将delegate
用作id
对我来说是一个糟糕的判断。我无法静态填写我的ListView
,因为有很多按钮,如Act
、Set
、Summon
等,每个按钮的可见性都由一个函数决定。所以它是一个动态模型。
您能否提供有关如何确定可见性的更多信息?也许用代码示例编辑你的答案【参考方案2】:
由于我无法发表评论,要求澄清,我将根据我的理解陈述我的假设:
您有多个ListModel
,其中包含在单击栏中相应的矩形项时应弹出的菜单信息。
一旦您单击此栏中的任何其他矩形,弹出的 ListView 将消失。 (另外:如果点击了栏或菜单之外的东西?或者选择了栏中的某个项目?)
我只会使用一个 ListView,并在单击按钮后更新/更改模型以及位置(例如边距),因此您不会有多个未使用的对象飞来飞去。 不显示任何东西,我认为设置一个空模型就足够了。
你也可以有一个函数列表。
Row
id: row
property var f: [a, b, c]
function a() console.log('a');
function b() console.log('b');
function c() console.log('c');
width: 300
height: 50
Repeater
id: rep
anchors.fill: parent
delegate: button
model: 3
Rectangle
id: button
width: 98
height: 50
border.color: 'black'
Text
text: "a"
anchors.fill: parent
MouseArea
anchors.fill: parent
onClicked: row.f[index]()
例如将调用函数 a、b 或 c - 取决于矩形的索引。
希望到目前为止,我能提供帮助。
【讨论】:
以上是关于QML 中的类似菜单栏的行为的主要内容,如果未能解决你的问题,请参考以下文章