Updating fontSize via function key call - calling functions in QML
-
I have a listview on which I need to dynamically update the font size when the F2 key is pressed. The XML document containing the listview data is quite complicated (speech, Braille and voice recognition are required) so it handled by the c++ code (coreMenu) making the QML really simple. The Qt documentation shows how to create a function and call it but is for a signal/slot and is all within one simple rectangle. Is there to a way access functions within a component when you are outside a component? I have not been able to find an example and I cannot work out the exact syntax :-S
@
import QtQuick 2.0Rectangle
{
id: theMenu
Component
{
id: menuEntryDelegateRectangle { id: menuItemContainer width: menuHolder.width height: menuEntry.height * 1.25 anchors.top: prompts.bottom function setFont(fontSize)/********** where does this function go??************/ { menuEntry.font.pointSize = fontSize } state: ListView.isCurrentItem ? "selected" : "notselected" Text { id: menuEntry font.pointSize: coreMenu.menuFontPointSize width: parent.width wrapMode: Text.WordWrap text: displayText clip: true }
.......
} Rectangle { id: menuContainer width: coreMenu.menuWidth height: (50 * 9) anchors.horizontalCenter: parent.horizontalCenter anchors.top: prompts.bottom color: "purple" ListView { id: menuHolder model: menuModel anchors.fill: parent opacity: 1 header: Rectangle { width: menuHolder.width height: 50 color: "#2A51A3" Text { id: header anchors.centerIn: parent text: coreMenu.getMenuTitle() font.pointSize: 20 color: "green" width: parent.width wrapMode: Text.WordWrap } } delegate: menuEntryDelegate focus: true Keys.onPressed: { if(event.key === Qt.Key_F1) { theMenu.visible = false } else if(event.key === Qt.Key_F2) { coreMenu.menuFontPointSize *= coreMenu.scale
/******** want to update the font here - i.e. menuEntry.font.pointSize***********/
}
..............
}
@If I put the function here
@
Rectangle
{function setFont(fontSize) { menuEntry.font.pointSize = fontSize } id: theMenu Component {
@
it compiles, runs and hits a brake point but outputs runtime errors:
file:///C:/Projects/GuideNext/qml/GuideNext/Menu.qml:11: ReferenceError: menuEntry is not defined
file:///C:/Projects/GuideNext/qml/GuideNext/main.qml:52: ReferenceError: menuContainer is not defined -
Hi,
Id's are unique within a component, but not accessible from outside the component.
Thus, "theMenu" will resolve to the top-level Rectangle from within the menuItemComponent's scope, but "menuItemComponent" will not resolve if used outside of the "menuEntryDelegate" component.Declaring a function in an object declaration (such as your setFont() function in the menuItemContainer Rectangle) will add a function attribute to that object instance's implicit type. You can call it as you would any other function. However, you need to be able to reference that function somehow, and this is often tricky with delegates.
Usually, a better way is (instead of calling the function directly) to set a property to which you have a binding in the delegate.
eg:
@
Item {
id: root
property int fontSizeComponent { id: delegateComponent Rectangle { id: delegateRect // this id is not resolvable from anything outside delegateComponent property int fontSize: root.fontSize // can resolve "root" since we're inside root's component } } Keys.onPressed: if (event.key == Qt_F2) root.fontSize = root.fontSize + 1
}
@Cheers,
Chris. -
Thought that was probably the case but did not know how to get round it. Property is an excellent idea thanks :-)
Have a good weekend.
-
One last thing. Any thoughts on how I would use the same variable idea to sort the menuEntry width? When changing the font size I need the width of menuEntry to be the font width but all the strings are different lengths so really I want the width to be the width of the largest string
@ Rectangle
{
id: menuItemContainer
width: menuEntry.width /automatically sizes but here for each entry but I need to use a var so I can store the largest width of an entry and it in the F2 key stroke/
height: menuEntry.height * 1.25
anchors.top: prompts.bottom
property double fontSize: theMenu.fontSizestate: ListView.isCurrentItem ? "selected" : "notselected" Text { id: menuEntry font.pointSize: fontSize //width: parent.width wrapMode: Text.WordWrap text: displayText clip: true }
@
-
Hi,
Similar code to the fontSize one: give root a "maxWidth" property. In each delegate, on f2, do:
@
var newWidth = (font metrics for each character in the string at the given font size);
if (root.maxWidth < newWidth) {
root.maxWidth = newWidth;
}
@Then you can bind your menuEntry's width to be the root.maxWidth value.
Cheers,
Chris. -
Thank you. That was what I was doing but there was a typo blush