I am trying the similar code to the tutorial, but I get 'QML Rectangle: Binding loop detected for property "width"' on the list view delegate. This happens only on messages where words are larger than listView.width and text wrapping happens. This happens all time. How can I fix it?
delegeate: Rectangle {
id: delegateFrame
width: Math.min(messageText.implicitWidth , listView.width)
height: messageText.implicitHeight
Label {
id: messageText
anchors.fill: parent
text: model.text
wrapMode: Label.Wrap
}
}
I am using Qt 5.8.
EDIT
Changed as Felix suggested in his answer, however it only changed the "width" word in the warning to "implictWidth".
delegeate: Rectangle {
id: delegateFrame
implicitWidth: Math.min(messageText.implicitWidth , listView.width)
implicitHeight: messageText.implicitHeight
Label {
id: messageText
width: parent.width
text: model.text
wrapMode: Label.Wrap
}
}
The cause here is probably height: messageText.implicitHeight and anchors.fill: parent. Reason:
change label height --> change delegate hight --> change anchors --> change label height ...
QML detects those loops and interrupts them. In some cases, you have to live with those, because it's the only way to archive your layout.
In your case however, there might be a solution. You can try one of the following, and see if they work:
use implicitHeight and implicitWidth in the delegate. Sometimes those remove the warnings
Instead of using anchors.fill bind the width only: width: parent.width. Since you already adjust the parents height to the child, the child does not need to change it's height to the parent
Use Layouts. For example RowLayout. They provide advanced ways of placing items and use attached properties to adjust how items are displayed
Related
I am reading the Qt doc to learn the Keyboard Focus in Qt Quick! I run the code which from the document. However, the result is different form the document! The codes are as follows.
main.qml
//Window code that imports MyWidget
Rectangle {
id: window
color: "white"; width: 240; height: 150
Column {
anchors.centerIn: parent; spacing: 15
MyWidget {
focus: true //set this MyWidget to receive the focus
color: "lightblue"
}
MyWidget {
color: "palegreen"
}
}
MyWidget.qml
Rectangle {
id: widget
color: "lightsteelblue"; width: 175; height: 25; radius: 10; antialiasing:
true
Text { id: label; anchors.centerIn: parent}
focus: true
Keys.onPressed: {
if (event.key == Qt.Key_A)
label.text = 'Key A was pressed'
else if (event.key == Qt.Key_B)
label.text = 'Key B was pressed'
else if (event.key == Qt.Key_C)
label.text = 'Key C was pressed'
}
}
The pic1 is the result form doc. And the pic2 is the result of my running which i just copy the code from doc and run it.
pic1
pic2
Is it a bug? Why the result are different?
The doc said:
We want the first MyWidget object to have the focus, so we set its focus property to true. However, by running the code, we can confirm that the second widget receives the focus.
Looking at both MyWidget and window code, the problem is evident - there are three types that set the focus property to true. The two MyWidgets set the focus to true and the window component also sets the focus. Ultimately, only one type can have keyboard focus, and the system has to decide which type receives the focus. When the second MyWidget is created, it receives the focus because it is the last type to set its focus property to true.
My question:
1.Why the result are different?In my result the first widget receives the focus.
2.Also, what is the meaning of"because it is the last type to set its focus property to true"in doc?
The doc you can get from here!
Qt doc
When I run the code I get the same result as you, but it does not matter. The point here is to understand that without FocusScope you have no control on which object receives the focus from the system (you have no guarantee in the order of creation of QML objects).
Did you try to set focus: true on the second MyWidget instead? If you try, the keyboard events will still be received by the first widget, except if you use a FocusScope.
Note that you can also remove focus: true from MyWidget.qml and you won't even need to manually add a FocusScope (it will automatically be managed by the application window).
try run with the following modification:
MyWidget { //the focus is here
color: "palegreen"
}
MyWidget {
focus: true //set this MyWidget to receive the focus
color: "lightblue"
}
MyWidget {
color: "palegreen"
}
I tested many times. The result is the same. Maybe the docs are outdated!
I am developing QT cross flat form application for Ubuntu and Windows. My Question is simple but as bit new to QT, i am not able to figure it out. I have bellow code in QML. I am using QT TextField in my qml. When QML is loaded for first time i want id_username TextField should show cursor by default at initial position (0) which is not happening. When i click same TextField using mouse, cursor is visible at initial position. I am doing focus: true which is not helpful. Next, i added cursorVisible: true with that cursor is visible when qml is loaded, but i am not able to type anything(Input anything) till i click on the TextField.
TextField
{
id: id_username
objectName: "id_username"
placeholderText: qsTr("username")
color: "#000000"
font.pixelSize: 20
cursorPosition: 0
selectByMouse: true
anchors.horizontalCenter: parent.horizontalCenter
focus: true
background: Rectangle
{
anchors.horizontalCenter: parent.horizontalCenter
implicitWidth: 200
border.color: id_username.focus ? "#000000": "#36404e"
border.width: id_username.focus ? 2: 1
radius: id_instruction.height / 4
}
}
Please let me know what i am doing wrong. Is there any onLoad function from where can call forceActiveFocus()
try this in TextField:
onVisibleChanged: if(visible) id_username.forceActiveFocus()
Reference link - http://www.qtcentre.org/threads/62655-How-to-gain-focus-onto-TextEdit-in-QML
I am testing on my desktop and can't seem to get qml to recognize the PressAndHold event.
Button
{
id: btn_draw
style: cgButtonStyle
width: isPortrait() ? Game.getBannerHeight() : Game.getBannerHeight() / 3
height: isPortrait() ? Game.getBannerHeight() : Game.getBannerHeight() / 3
MouseArea
{
onPressAndHold: iPod4.play()
}
// Much more code
Am I missing a signal somewhere or something? Do I need to add anything else in order for QML to recognize the PressAndHold event? Is it possible other code is preventing PressAndHold from working?
You're missing the MouseArea anchors... the mouse area is zero-sized, and so you can't click it...
Simply modify like that:
MouseArea
{
anchors.fill: parent
onPressAndHold: iPod4.play()
}
and it would work.
I'm trying to figure out what component that would be best to use for a active chats control.
I've attached an image with the layout that I'm aiming for.
Basically I want to add an icon to the left of each conversation, depending if the conversation is active or not. The middle column is the name of the conversation and the last column is an indicator if there are new messages for this conversation. However, if the row is selected the indicator should switch out to a close conversations button.
I've through about using:
- Listview, however this would not give me multiple columns?
- Treeview
- Tableview - this might be the best solution. However in unsure of how to add icons and buttons to different cells
Which one would be my best bet here?
I think it depends on API you want to achieve. Most importantly, who will be the close handler/listener:
You can go for a table view with three different delegates. This way the caller is responsible to set up the close event.
Or you can make it list view, which internally creates listView/GridView. This way the conversation itself would be the listener to the close event.
It's up to you to decide which of these (there may be more) is more suitable to your existing codebase
If you have a simple delegate to implement (and you work in QML), you can really use a ListView to get the job done.
Here is a self-contained prototype of your layout. Change Rectangle by Image. You see that color vary accordingly as the model give an odd or even number. You can in the same way change the Component to load, the source of an Image, whatever you can imagine.
import QtQuick 2.0
Rectangle {
width: 360
height: 200
ListView {
anchors.fill: parent
model: 3
delegate: Rectangle {
id: rect
width: parent.width
height: 60
property bool selected: false
color: selected ? "darkblue" : "transparent"
Rectangle {
id: bubbleIcon
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: 40
height: 40
color: "lightblue"
}
Text {
id: chatName
anchors.left: bubbleIcon.right
anchors.leftMargin: 10
height: parent.height
verticalAlignment: Text.AlignVCenter
text: "chat" + modelData
}
Rectangle {
id: notificationIcon
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
width: 40
height: 40
//just an dummy example to show how to change representation base
//expression binding
color: (modelData % 2 === 0) ? "lightGreen" : "red"
}
MouseArea {
anchors.fill: parent
onClicked: {
selected = ! selected;
}
}
}
}
}
I'm trying to set a custom style to a group of options belonging to a dropdown or a Radio Group. I'm searching all over and it seems impossible. At least I would like to decrease the size of the letters in the text of each option because is too big! and crashes my UI.
Here's and example of what I need:
RadioGroup {
id: groupOrigin
objectName: "groupOrigin"
Option{
text: "text to display"
//This text default style is what I'm trying to change. Please help!.
}
}
thanks!
for Radio group you can achieve this using custom implementation. Take a label and place it after the radio group did not provide text inside the options tag. So whatever style you want to apply can be done using label.
On label you can set the font size, color and other style parameter you want to apply.
Please check the source code below for this custom radio button. I did this in the QML you can achieve same in C++.
// The Component title.
Label {
id: titleLabel
text: ""
textStyle {
base: SystemDefaults.TextStyles.SmallText
alignment: TextAlignment.Center
}
layoutProperties: StackLayoutProperties {
horizontalAlignment: HorizontalAlignment.Fill
}
}
// The radio group presenting the different curves.
RadioGroup {
id: radioGroup
Option {
text: "Height"
}
}