QML: How can I change dynamically label in legend in ChartView? - qt

For a ChartView I have declared a simple LineSeries:
LineSeries {
id: lineSeries1
name: varName
axisX: axisX
axisY: axisY1
}
I want the name to be able to be changed when clicked. How can I do it? Thank you!

Related

Change fusion style colors in QML dynamically

I'm developing QML application using Fusion style. I'm using Qt 5.15 lts.
I want to make a function which switch color themes(light mode, dark mode, etc.) in runtime.
The documentation says that changing the color system of fusion style can be done by modifying palette object in QML.
I believe it will be easily done in ApplicationWindow type, but I have to use my custom Window object, rather than ApplicationWindow.
So I tried to it in C++, like below.
// #theme_dark_ and #theme_light_ are pre-defined palette object.
Q_INVOKABLE void Backend::SetDarkMode(const bool flag) {
qGuiApp->setPalette(flag ? theme_dark_ : theme_light_);
}
I checked setPalette method works before starting QML application(QGuiApplication::exec), but it didn't when QML app is running.
Is there any way to modify palette in Window type in QML, or calling QCoreApplication::setPalette in QML app runtime?
Thanks.
In the following example, I have a Page component where I can set the palette which will be inherited by all its children:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
palette: darkMode.checked ? darkTheme : lightTheme
Flickable {
id: flickable
anchors.fill: parent
contentWidth: columnLayout.width
contentHeight: columnLayout.height
clip: true
ScrollBar.vertical: ScrollBar {
width: 20
policy: ScrollBar.AlwaysOn
}
ColumnLayout {
id: columnLayout
width: flickable.width - 40
CheckBox {
id: darkMode
text: checked ? qsTr("Dark Mode") : qsTr("Light Mode")
checked: false
}
Label {
text: qsTr("Sample Label")
}
CheckBox {
text: qsTr("Sample CheckBox")
}
RadioButton {
text: qsTr("Sample Radio Button")
}
Button {
text: qsTr("Sample Button")
}
ComboBox {
Layout.preferredWidth: 200
model: [ "ComboValue 1", "ComboValue 2", "ComboValue 3" ]
}
Slider {
from: 0
to: 100
}
ListView {
model: 20
Layout.preferredHeight: contentHeight
delegate: ItemDelegate {
text: "ListItem " + (index + 1)
onClicked: ListView.view.currentIndex = index
}
}
}
}
Palette {
id: darkTheme
alternateBase: "#000"
base: "#000"
button: "#111"
buttonText: "#fff"
dark: "#666"
highlight: "#d73"
highlightedText: "#000"
light: "#000"
mid: "#444"
midlight: "#333"
placeholderText: "#80000000"
shadow: "#888"
text: "#fff"
window: "#222"
windowText: "#fff"
}
Palette {
id: lightTheme
alternateBase: "#fff"
base: "#fff"
button: "#eee"
buttonText: "#000"
dark: "#999"
highlight: "#38c"
highlightedText: "#fff"
light: "#fff"
mid: "#bbb"
midlight: "#ccc"
placeholderText: "#80000000"
shadow: "#777"
text: "#000"
window: "#eee"
windowText: "#000"
}
}
You can Try it Online!

MapCircle not rendering in QML when using Mapbox

I have an issue with trying to display QML MapCircle on a Window when I use the Mapboxgl plugin.
I have a model which is populated from C++ and is shown on the map when the user clicks a button. Here is a snippet:
MapItemView{
model:disksModel
delegate:MapCircle{
border.color: "red"
border.width: 1
center: QtPositioning.coordinate(model.latitude, model.longitude)
radius: 53
}
}
When I use osm or esri as my plugin,
plugin:Plugin{
name:"esri"
}
I get the following which is what I expect: but using mapbox, the circles aren't displayed.
plugin:Plugin{
name:"mapboxgl"
PluginParameter {
name: "mapboxgl.mapping.use_fbo"
value: true
}
PluginParameter {
name: "mapboxgl.mapping.items.insert_before"
value: "aerialway"
}
}
However, if I change my model to use something like a MapQuickItem and then use something like a Marker,
MapItemView{
model:disksModel
delegate:MapQuickItem{
sourceItem: Image{
id:waypointMarker
opacity: .75
sourceSize.width:80
sourceSize.height:80
source: "../images/marker.png"
}
coordinate: QtPositioning.coordinate(model.latitude, model.longitude)
anchorPoint.x: waypointMarker.width/2
anchorPoint.y: waypointMarker.height/2
}
}
The coordinates of interest are then marked on the screen
. Does anyone know a workaround or fix for this?

QML: Multi-level Menu from ListModel

I have an example multi-level ListModel:
ListModel{
id: myModel
ListElement{
name: "File"
subItems:[
ListElement{
name: "Open"
},
ListElement{
name: "Open Recent"
subItems:[
ListElement{
name: "Bla.txt"
}
]
},
ListElement{
name: "Save"
},
ListElement{
name: "Save as"
},
ListElement{
name: "Exit"
}
]
}
ListElement{
name: "Edit"
subItems:[
ListElement{
name: "Undo"
},
ListElement{
name: "Redo"
},
ListElement{
name: "Select All"
}
]
}
ListElement{
name: "Help"
subItems:[
ListElement{
name: "About"
}
]
}
}
Which I want to display as Menu. From here I know how to iterate model inside of Menu component. But because I have multi-level structure I should check either second level is Menu or MenuItem. Therefore I use Loader and choose which component to load(check if subItems of the element is undefined):
MenuBar{
id: menuBar
Instantiator{
id: menuBarRepeater
model: myModel
onObjectRemoved: menuBar.removeItem( object )
delegate: Loader{
sourceComponent: myModel.get(index)["subItems"]? subMenuLoader : menuItemLoader
onLoaded: {
item.name = model.name;
if(myModel.get(index)["subItems"]){
item.parentIndex = index;
item.model = model
menuBar.insertMenu( index, item )
}else{
menuBar.insertItem( index, item )
}
}
}
}
}
Finally I need to add one more Instantiator for third level of menu. I could do it recursively, but for example purpose I'll assume that I have max. 3 levels. So the components that will be loaded in code above are:
Component{
id: menuItemLoader
MenuItem{
property var name
text: name
}
}
Component{
id: subMenuLoader
Menu{
id: subMenu
property var name
property var parentIndex: index
property var model
title: name
Instantiator{
model: model
onObjectRemoved: menuBar.removeItem( object )
delegate: Loader{
sourceComponent: myModel.get(parentIndex)["subItems"].get(index)["subItems"] ? subMenuLoader : menuItemLoader
onLoaded: {
item.name = model.name;
if(myModel.get(parentIndex)["subItems"].get(index)["subItems"]){
subMenu.insertMenu( index, item )
}else{
subMenu.insertItem( index, item )
}
}
}
}
}
}
My problem is that the model that will be passed to the second level is QQmlDMListAccessorData and is not iterable. Is there any way to get children of the Intantiator model item?
So, the workaround I have found is: instead of passing the model (which has type QQmlDMListAccessorData) to subMenu, as a second-level Instantiator model I used myModel.get(parentIndex)["subItems"].get(index), which addresses to ListElement, which for QML has type QQmlListModel(%index%) and can be used exactly as its parent (myModel itself)

Material Style In Qml Does Not Load Colors

i used methods here to use material design in my QtQuick project and used Accent and Themes from here controls loading in material style correctly in normal qml files , but in qml files loaded by loader result is like this:
this loader is in main.qml :
Loader{
id:myLoader
anchors.fill: parent
source: "LoginPage.qml"
}
and here is my dynamic qml file
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.3
import QtGraphicalEffects 1.0
Rectangle{
Material.theme: Material.Dark
Material.accent: Material.Teal
property string error_msg: ""
id: loginPage
Button {
id: button
width: 80
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 0
font.family: "B Nazanin"
enabled: webView.loadProgress == 100 ? true:false
KeyNavigation.tab: button1
Material.accent: Material.Orange
onClicked: {
login()
}
}
}
The dark there is presumed to have a dark background. It will not set your window background for you, it only affects GUI controls. And the button in particular doesn't use use the accent color, just the foreground color, unless toggle is enabled, in which case it will use the accent color to signify that.
Material.theme: Material.Dark
Material.accent: Material.Teal
Rectangle {
anchors.fill: r2
color: "#262626"
}
Row {
id: r1
Button {
text: "test"
checkable: true
Material.accent: Material.Orange
}
Button {
text: "test"
checkable: true
}
}
Rectangle {
anchors.fill: r2
}
Row {
id: r2
anchors.top: r1.bottom
Button {
text: "test"
checkable: true
Material.accent: Material.Orange
}
Button {
text: "test"
checkable: true
}
}
As you see, on a white background, the dark theme button looks blurry and washed out. If you want to set the button color, that would be the Material.background whereas the text would be Material.foreground.
I had a similar problem.
Just use ApplicationWindow as your root element and it will work.
And additionally you have to load Material before instantiating QML.
QGuiApplication application(argc, argv);
QQmlApplicationEngine engine;
QQuickStyle::setStyle("Material");

QML TableView Custom delegate: How to make ellipsis for too long text

I want to display a QFileSystemModel in a QML TreeView and need a custom delegate, as I want to add a check box next to a file. This is what I have:
TreeView {
id: view
anchors.fill: parent
sortIndicatorVisible: true
model: fileSystemModel
rootIndex: rootPathIndex
selection: sel
selectionMode: 2
TableViewColumn {
id: namecolumn
title: "Name"
role: "fileName"
resizable: true
width: parent.width-sizeWidth-dateWidth-scrollBarWidth
delegate: fileCheckDelegate
}
Component {
id: fileCheckDelegate
Row{CheckBox{}
Text{text: root.getText(model.fileName)}
}
}
However, I have a problem with long filenames going over the column border. The default delegate truncates the text and adds ellipsis to the truncated text. I would like to do the same in my custom delegate, but don't know how this should be done.
As you can see, I tried with a custom getText function, but I don't know which widths and positions to use there for deciding whether a text should be truncated or not
Edit: I found that setting Text.ElideRight on my Text component would do the ellipsis, but I need to set an explicit width. How can I set the width of my Text component right then?
Ok, this does the trick:
TreeView {
id: view
anchors.fill: parent
sortIndicatorVisible: true
model: fileSystemModel
rootIndex: rootPathIndex
selection: sel
selectionMode: 2
TableViewColumn {
id: namecolumn
title: "Name"
role: "fileName"
resizable: true
width: parent.width-sizeWidth-dateWidth-scrollBarWidth
delegate: fileCheckDelegate
}
Component {
id: fileCheckDelegate
Row{CheckBox{
id: cbox
}
Text{text: model.fileName
width: namecolumn.width-x-cbox.width
elide: Text.ElideRight
}
}
}

Resources