QML text scroll - c++

I am using C++ and QML to create a nice interface.
I would like to have a "console view", where plenty to text is printed through time.
However, when the text of a text item or webview content grows, the view does not "scroll down".
How can I make the text on the bottom of the text/webview item always stay visible ?
I have tried playing with flickable and the_webview.evaluateJavaScript + window.scrollTo , but I could not get them to do what I want.
This seems a fairly simple piece of UI, but I am having serious troubles to do it with QML.
Thanks for you answer.

Yeah I'd use a Flickable containing a Text object. Whenever you add text to the Text, check its paintedHeight, and adjust the Flickable's contentY if it's got any bigger.

Maybe you should consider using a ListView and have the messages as items in the view. Then you could use ListView::positionViewAtEnd.

funkybro answers inspired my final solution:
function scroll_to_bottom() {
flickabe_item.contentY =
Math.max(0, webview_item.height - flickabe_item.height);
return;
}
Thanks !

My solution to this was to vertically flip both the content and Flickable. This way the text ends the right way up and is naturally anchored to the bottom of the flickable area.
It might be more efficient too since the transform is handled by OpenGL behind the scenes.
Flickable {
id: flick
anchors.fill: parent
contentHeight: text.height
Text {
id: text
width: parent.width
transform: Scale { yScale: -1; origin.y: text.height/2 }
}
transform: Scale { yScale: -1; origin.y: flick.height/2 }
}

Related

Swiftui list: trigger an action on tap and mimic basic select then auto-unselect

I'm starting to learn swiftui and I've run into a problem that is both very basic and easily solvable in UIKit; but after spending days searching the internet and watching WWDC videos I've found no native solution.
The premise is simple: I have an array of songs I want to display in a list; when a user taps on a song view it should highlight the view on press, unhighlight after release, and then play the song (ie trigger an action). Sounds simple right?
Here's what I tried and spent way too much time on:
Using List(selection) + .onEvent(changed): I end up with a UUID (because i've only gotten selection to work with a UUID) that I then have to check against an array of songs to match AND the cell won't unhighlight/select itself; even when I try to manually set the State variable to nil or another generated UUID.
Using .onTap (either on or in the cell): I have to tap on the text of the cell to trigger onTap so I get a lot of taps that just don't work (because I have lots of white space in the cell). I also don't get a nice UI color change on press/release.
So after spending hours trying many different things I've finally come up with a solution and I basically wanted to create an account and share it to hopefully help other developers in my position. Because this so very annoyed me that something so basic took so much effort and time to do.
In the end the best solution I came up with was this:
Using ZStack and an empty button:
edit: I found I need to include and hide the content otherwise the button doesn't grow to fill the space (seems in lists it does for some reason). Though not sure what the hit on performance is of rendering the content twice when hiding it. Maybe a GeometryReader would work better?
struct SelectionView: ViewModifier {
let onSelect: () -> Void
func body(content: Content) -> some View {
ZStack (alignment: .leading) {
Button {
onSelect()
} label: {
content
.hidden()
}
content
}
}
}
extension View {
func onSelection(_ selection: #escaping () -> Void) -> some View {
self.modifier(SelectionView(onSelect: selection))
}
}
then to use it:
SongCell(song: song)
.onSelection {
// Do whatever action you want
}
No messing around with list selection, no weird tap hit boxes, and get the press/release color change. Basically put an empty button in a ZStack and trigger off it's action. Could possibly cause tap/touch issues with more complicated cells (?) but it does exactly what I need it to do for my basic app. I'm just not sure why it took so much effort and why apple doesn't support such a basic use case by default? If I've overlooked something native please do inform me. Thanks.
I got the basic idea what you are trying to do. I'm Going to show simple example. Maybe using this you will be able to find proper solution.
First let's create a color : -
#State var colorToShow : Color = Color.blue
Now in body we have our ZStack or Your cell that we want to deal with : -
ZStack{
colorToShow
}.frame(width: 50, height: 50).padding()
.onLongPressGesture(minimumDuration: 3) {
print("Process Complete")
colorToShow = .green
} onPressingChanged: { pressing in
if pressing {
print("Pressing")
colorToShow = .red
} else {
print("Pressing Released")
colorToShow = .blue
}
}
Here we are using .onLongPressGesture. You can set minimum duration on which you want to perform action. Now on process completion You set what you want to do. OnPressingChange give you a bool value that changes according to user is pressing that button or not. Show color change(Highlight) or do action while bool value is true. When user release button do action or unhighlight since bool value turns false.
Hope you find it useful.

Qt/QML: Text with inline QML elements

We are building a graphical user interface with QtQuick/QML. We have some dynamic, multi-line text coming from a database, which should be displayed in the application. Currently, we are using the Text element to display the text. However, we need some QML components inline embedded into the text. For this, the text coming from the database contains placeholders such as ::checkbox|1:: which should then be replaced and displayed by the program.
In HTML, this is easy, you can simply mix inline elements with text to produce a result like this:
but in QML, this seems to be more difficult, as Text elements cannot be word-wrapped into two halves if there is not enough space (both the text and the container size should be dynamic).
The best solution we could come up with, is creating a Flow layout with one Text element for each word, but this seems too hacky.
Using RichText with HTML is not enogh, since we really need our custom QML elements in the text.
Also, we want to avoid using a WebView due to performance reasons.
Is there a sophisticated way to implement this with QML/C++ only?
You can create custom widgets and embed them into QML:
Writing QML Extensions with C++
I haven't tried placing something in the middle, but I did try adding a tag to the beginning (and I might try adding a tag at the end).
QML's Text has a lineLaidOut signal that let's you indent the first line of text.
http://doc.qt.io/qt-5/qml-qtquick-text.html#lineLaidOut-signal
Here's what I did:
Text {
text: issue.summary
onLineLaidOut: {
if (line.number == 0) {
var indent = tagRect.width + tagRect.rightMargin
line.x += indent
line.width -= indent
}
}
Rectangle {
id: tagRect
implicitWidth: padding + tagText.implicitWidth + padding
implicitHeight: padding + tagText.implicitHeight + padding
color: "#400"
property int padding: 2
property int rightMargin: 8
radius: 3
Text {
id: tagText
anchors.centerIn: parent
text: issue.product
color: "#fff"
}
}
}

BlackBerry 10 development- TextField

Guys I am developing the basic app in BlackBerry 10 and I want to get text which is in TextField (in cpp). I am trying to find method for that but not getting the right one .So can anyone please tell me how to get the value from TextField in cpp (not in qml) ???
Well, the first thing you need to do is expose your QML TextField to C++. This is done with an object name property ala:
TextField {
objectName: "myTextField"
...
}
Next, find this child from your C++:
QmlDocument *qml = QmlDocument::create("asset:///my.qml");
Container *root = qml->createRootObject<bb::cascades::Container>(); //or whatever the root control is
TextField *textField = root->findChild<TextField*>("myTextField");
From then on, simply use textField->text().
We have 3 parts in this problem
First on in Qml your text area and bottom when clicked send text area to function in c++
TextField {
id: n2
}
Button {
id: button
text: "send text"
onClicked: {
app.sendtext(n2.text)
}
Second part your c++ function in your ApplicationUI to receive this text
QString ApplicationUI::sendtext(QString txtarea)
{
QString text = txtarea;
return text;
}
Third and final part in your ApplicationUI.h u must make this function INVOKABLE to access it in Qml
so u will need this line
Q_INVOKABLE QString sendtext(QString txtarea);

Settings menu UI implementation

I'm trying to implement a BB10 settings menu, looking like the one in the Calendar app for example. The question here is, which components should I use? Using a ListView with an XML model looks great, but is incompatible with translation. Using a C++ model looks overkill for a simple menu with a couple of entries…
There's probably an established pattern somewhere, but I can't find it.
Screenshot of the Calendar app settings view
What you want is the expendable content property of the title bar:
I would create a QML object that you can re-use for each entry with properties for title and image.
So for example, something perhaps like this:
SettingEntry.qml
Container {
property alias title:title.Text
signal click()
TextView {
id: title
text: "[title goes here]"
}
gestureHandlers: [
TapHandler {
onTapped: {
click();
}
}
]
}
Then in your settings page you would use it like a normal object:
Page {
Container {
SettingEntry {
title: "General"
onClick: {
//open general page
}
}
SettingEntry {
title: "Invitation Settings"
}
}
}
The above is obviously very simplified, you would want to include an icon image, add translation code and add visual adjustments like filling the width and padding.
It should however give you a good idea of where to start.
I also included a gesturehandler and signal to show you how to handle events such as a click.

Qt checkbox/toolbutton with custom/distinct check/unchecked icons

I need to have a checkbox like control where the checked and unchecked states use a custom graphic. I've looked at all the docs for QToolButton and QCheckBox, along with QIcon but couldn't find any combination that does what I want.
I just want to use one icon (pixmap actually) in the unchecked state, and a different one in the checked state.
This feels like it should be easy, but the solution (short of a custom control) is eluding me.
I've tried using a style sheet as well, and QToolButton:checked with a background-image kind of works but I can't get the layout correct -- it's not positioned/sized as with an icon.
Use ::indicator sub-item. the code below works excellent for me...
QCheckBox::indicator {
width: 18px;
height: 18px;
}
QCheckBox::indicator:checked
{
image: url(.../Checkbox_checked_normal.png);
}
QCheckBox::indicator:unchecked
{
image: url(.../Checkbox_unchecked_normal.png);
}
QCheckBox::indicator:checked:hover
{
image: url(.../Checkbox_checked_hovered.png);
}
QCheckBox::indicator:unchecked:hover
{
image: url(.../Checkbox_unchecked_hovered.png);
}
QCheckBox::indicator:checked:pressed
{
image: url(.../Checkbox_checked_pressed.png);
}
QCheckBox::indicator:unchecked:pressed
{
image: url(.../Checkbox_unchecked_pressed.png);
}
QCheckBox::indicator:checked:disabled
{
image: url(.../Checkbox_checked_disabled.png);
}
QCheckBox::indicator:unchecked:disabled
{
image: url(.../Checkbox_unchecked_disabled.png);
}
This must be entered as a StyleSheet. Do this via the Design editor by right click on the check box and selecting "Change stylesheet...".
You may also include and use your icons as resources:
QCheckBox::indicator:checked {image: url(:/circle-green.png);}
QCheckBox::indicator:unchecked {image: url(:/circle-red.png);}