I would like to know which fonts I can use in a QML environment for the font.family property. Are these fonts system-specific or are they built into the framework? Is there any way to list all available fonts?
This code will list all the accepted font families:
ListView {
anchors.fill: parent;
model: Qt.fontFamilies()
delegate: Item {
height: 40;
width: ListView.view.width
Text {
anchors.centerIn: parent
text: modelData;
}
}
}
The fonts are system-specific so you should see what your system proposes.
If you are using QtCreator :
try putting your mouse over the end of your component name
Text <here> {
...
}
You should see a yellow light, click on it and you'll have an interface that allows to choose the font.
You can also access the interface with ctrl + alt + space while inside the component. Or with right click.
This is a system-specific list of fonts, but you can specify external font from resources (QRC)
You can improve the previous answer by adding this
Text {
font.family: modelData
anchors.centerIn: parent
text: modelData;
}
Related
I am trying to change the color of the background of the comboBox when pulling till you have a "bounce effect". Cause my background color in the comboBox is black but on the bounce effect the background of the background is white.
If it's not possible I would at least want to be able to desactivate this effect "bouncing effect".
I tried as describe here but it didn't work.
Thanks in advance for your help.
The white background you are seeing is from the popup property embedded in the ComboBox, specifically its background.color. To customize this, the documentation recommends you re-implement the entire popup as well as its ListView contentItem. Re-implementation of this type can be quite painful as you must re-implement all behaviors as well as visual characteristics. I find this to be overkill when you only want to tweak a property or two that already exists.
An easier way is to set the properties at runtime. Here is a working example that shows how to modify your "bounce effect" color as well as modify effect itself:
ComboBox {
id: comboBox
model: ["first", "second", "third"]
delegate: Rectangle { // My remake of your black-background delegates
color: "black"
implicitHeight: 20
implicitWidth: comboBox.width
Text {
anchors {
centerIn: parent
}
text: modelData
color: "lime"
}
}
// At runtime, reach into the comboBox.popup and set the background and boundsBehavior:
Component.onCompleted: {
comboBox.popup.background.color = "black" // Set "bounce" background color to black
comboBox.popup.contentItem.boundsBehavior = Flickable.StopAtBounds // Change/stop "bounce" behavior
}
}
I want to partially change the style of a control without affecting it's rendering otherwise. Let's take a button as an example and create a MyButton.qml containing:
Button {
id: mybutton
style: ButtonStyle {
label: Text {
renderType: Text.NativeRendering
font.family: "Helvetica"
font.pointSize: 20
text: control.text
}
}
}
Expected: a system theme colored button with an ugly font in it.
Got: default-styled button ignoring the system palette (while the rest of the application is themed fine)
Why does the overriding style ignore the system palette? What is the right way to do it?
EDIT:
Example:
I want to write an app in QtQuick that dynamically loads content. I decided to use Loader. Now I have a problem, which overwhelms me. I thought I would spend two minutes on that, but it took me two days and my problem is still unresolved.
I want to load an object from a .qml file, when the button is clicked. Clicking different buttons will set different properties to that object. The object is a simple rectangle with text within it. It has properties like width, height, text, color of rectangle and color of text. The problem is that loading the rectangle with different parameters DOESN'T change anything else than the color of the rectangle. I tried so many combinations of naming, property aliases etc, but it gave me nothing. Only color changes. Let me introduce you my code:
//StartStateContent.qml --> I wish to use Loaders in my Finite States Machine, hence the name
import QtQuick 2.0
import QtQuick.Controls 2.0
Rectangle {
id: startStateContent
property int myWidth
property int myHeight
property color myColor
property alias myText: name.text
property string myText2
property alias myTextColor: name.color
property color myTextColor2
// width: myWidth
// height: myHeight
color: kolor
Text {
anchors.centerIn: parent
id: name
text: "test"
//text: myText2
color: "yellow"
//color: myTextColor2
}
}
And a snippet of main.qml
Window {
visible: true
id: root
width: 500
height: 500
title: qsTr("Hello World")
Loader
{
id: pageLoader
anchors.top: root.top
anchors.left: root.left
width: root.width
height: root.height/2
}
Button{
id: but1
text: "red"
anchors.top: pageLoader.bottom
anchors.left: root.left
height: root.height/2
onClicked: {
pageLoader.setSource("StartStateContent.qml", {"myColor": "red"}, {"myTextColor" : "white"})
console.log("button red clicked")
}
}
Button{
id: but2
text: "green"
anchors.top: pageLoader.bottom
anchors.left: but1.right
height: root.height/2
width: root.width/2
onClicked: {
pageLoader.setSource("StartStateContent.qml", {"myColor": "green"}, {"myTextColor" : "green"})
console.log("button green clicked")
}
}
DSM.StateMachine{
id: stateMachine
initialState: startState
running:true
onStarted: {
pageLoader.setSource("StartStateContent.qml", {"myColor": "blue"}, {"myTextColor" : "orange"})
console.log("App started")
}
Here I try to set only color and text.color, but earlier I tried to change text rectangle size too. At first, I tried to just write {"height" : 100}. Then {"height" : "100"}, {"height" = 100}, etc. Then I added property myHeight (commented in first file), but with no luck. Then I did the same to text. Later I tried to create an alias property of text. I did that to every property (but cut that out of that example to spare space), without any success. Of course I changed also the anchors of loader. I tried to use anchors, to use explicitly set x,y, width, height; to use centering. Independently of attempts, the very thing that is being changed when I click buttons is color of the rectangle. Unfortunately, the only example of using Loader with properties in official Qt Documentation changes only the color property, so it doesn't help me.
My question is: how can I change properties (other than color) of a loaded object, using Loader.setProperty() method? Thank you in advance.
Btw, that is my first post here, so Hello Qt World:)
And sorry for possible lingual mistakes, as english isn't my native language.
I got the answer from official QtForum:
Instead of using
pageLoader.setSource("StartStateContent.qml", {"myColor": "red"}, {"myTextColor" : "white"})
one should use
pageLoader.setSource("StartStateContent.qml", {"myColor": "red", "myTextColor" : "white"})
because the setSource method expects an object. Works 100% that way!
I really like QML. I like how I can define components (comparable to classes) and their properties, and instantiate them from somewhere else (comparable to objects).
I can define, let's say, a button, having some look and feel, and a label text on it. This could be done, for example, using this component definition (Button.qml):
Item {
id: button
property string label
anchors.fill: parent
Rectangle {
anchors.fill: parent
radius: 10
color: "gray"
Text {
anchors.centerIn: parent
font.pixelSize: 20
text: button.label
color: "white"
}
}
}
and instanciated in this main file (main.qml):
Rectangle {
width: 300
height: 200
Button {
anchors.centerIn: parent
anchors.margins: 50
label: "Hello button!"
}
}
But I see the following restriction: I can only define a button template with some properties, not with some placeholder. All children defined in the instance will be direct children, at least per default, and I want to change this behavior.
Let's say I want to place an item (let's say an image, but I don't want to tell the definition of Button that it will be an image) in the button. I imagine something like this:
Item {
id: button
property Item contents <-- the client can set the placeholder content here
anchors.fill: parent
Rectangle {
anchors.fill: parent
radius: 10
color: "gray"
Item {
id: placeholder <-- where the placeholder should be inserted
}
}
Component.onCompleted: {
// move the contents into the placeholder...
}
}
How can I achieve this? I don't know if using Component.onCompleted is the correct way. Note that, however, that in my case the contents will never change afterwards (at least in my current design of the application...).
Also, I want anchoring to work within the placeholder. For example, if I define the contents to be a Text element, being centered in its parent (which will first be the template itself). Then my code moves this Text instance into the placeholder and the parent anchors should then be those of the placeholder item, not the template item.
I found a much nicer answer to this question, suggested in a presentation of the Qt Developer Days 2011 "Qt Quick Best Practices and Design Patterns".
They use default property alias ... to alias the child items to any property of any item. If you don't want to alias the children but give the alias property a name, just remove default. (Literal children are per QML definition the value of the default property.)
Item {
id: button
default property alias contents: placeholder.children
anchors.fill: parent
Rectangle {
anchors.fill: parent
radius: 10
color: "gray"
Item {
id: placeholder <-- where the placeholder should be inserted
}
}
}
Necro answering in case someone else end up here as I did.
In Qt5 somewhere along the line the default property became "data" and not "children".
This makes it possible to add other object types than "Item".
e.g. Connections can be added as well (to answer my own question above)
So in Qt5 you should do:
Item {
id: button
default property alias contents: placeholder.data
anchors.fill: parent
Rectangle {
anchors.fill: parent
radius: 10
color: "gray"
Item {
id: placeholder <-- where the placeholder should be inserted
}
}
}
Note the:
placeholder.data instead of placeholder.children
Also please note that you don't have to use the alias name contents - this can be anything you like. An example:
Item {
id: button
default property alias foo: placeholder.data
...
}
Actually, the correct answer from what I've heard is to use a QML Loader to accomplish what you want.
[that being said; I haven't actually tried it yet but it's on my near-term to-try list and looks fairly straight forward]
Also, search stackoverflow for other "QML Loader" questions as there are a number that will help you get started.
You can move the item(s) (if you want to support multiple items within the placeholder) using this piece of code:
property list<Item> contents
Component.onCompleted: {
var contentItems = [];
for(var i = 0; i < contents.length; ++i)
contentItems.push(contents[i]);
placeholder.children = contentItems;
}
Note that you do not have to provide a list of Items for the contents property, as single values will be accepted by the QML engine also for list properties.
In short (to show the idea):
import QtQuick 1.1
Item {
width: 200
height: 100
//<-- the client can set the placeholder content here
property Item contents: Rectangle {
anchors.fill: parent
anchors.margins: 25
color: "red"
}
Rectangle {
id: container
anchors.fill: parent
radius: 10
color: "gray"
//<-- where the placeholder should be inserted
}
Component.onCompleted: {
contents.parent = container
}
}
Somewhat longer version (supporting contents reassignment):
import QtQuick 1.1
Item {
width: 200
height: 100
//<-- the client can set the placeholder content here
property Item contents: Rectangle {
//anchors can be "presupplied", or set within the insertion code
//anchors.fill: parent
//anchors.margins: 25
color: "red"
}
Rectangle {
id: container
anchors.fill: parent
radius: 10
color: "gray"
//<-- where the placeholder should be inserted
//Item {
// id: placeholder
//}
}
//"__" means private by QML convention
function __insertContents() {
// move the contents into the placeholder...
contents.parent = container
contents.anchors.fill = container
contents.anchors.margins = 25
}
onContentsChanged: {
if (contents !== null)
__insertContents()
}
Component.onCompleted: {
__insertContents()
}
}
Hope this helps :)
SDK: Qt Creator 2.4.1
Target: Nokia N9 and Windows 7
If I do the following in a qml file
import QtQuick 1.1
import com.nokia.meego 1.0
Page {
id: myShowChangeLogPage
TextEdit {
id: changeLogArea
anchors.top: titleBackground.bottom
width: parent.width
height: 300
text: "1\n1\n1\n1\n2\n1\n1\n1\n1\n1\n3\n1\n1\n1\n4\n1\n1\n1\n1\n5\n1\n1\n1\n6\n1\n1\n1\n7\n1\n1\n1\n8\n\n\n\n\n9"
font.pixelSize: 20
textFormat: TextEdit.AutoText
readOnly: true
wrapMode: TextEdit.WordWrap
}
}
The TextEdit area do not behave as I expected.
The String will be printed outside the size of the TextEdit area, that is,
it continues beneath the bottom screen edge.
There is no scrollbar/slider to the right
I was expecting that the the TextEdit element should automatically create a
scrollbar/slider if the string is to large to fit within the boundaries.
I have been told that TextEdit should do this and there is no need for a Flicker
or ScrollArea.
I have tried other type of components such as Text and TextEdit and also encapsulate
the TextEdit in a rectangle without any luck.
Regards
I read this right at the beginning of the documentation regarding the TextEdit element:
Note that the TextEdit does not implement scrolling, following the
cursor, or other behaviors specific to a look-and-feel.
There is also a complete example of how to implement scrolling for following the cursor.
TextEdit in qml doesn't implement scrolling. You must to use another one, such as TextArea (https://doc.qt.io/qt-5/qml-qtquick-controls2-textarea.html), then place it inside a ScrollView. Here's an example:
// Creating a scrollable TextEdit
ScrollView {
id: view
anchors.fill: parent
TextArea {
text: "TextArea\n...\n...\n...\n...\n...\n...\n"
}
}