I have a problem with the usage qml components from another qml file. I have 2 files, main.qml and menu.qml (menu.qml is in another folder called menu). In the menu.qml I have my menu, which I want to use in main.qml
import QtQuick 2.9
import QtQuick.Controls 2.4
Menu {
id: routingMenu
width: maximumWidth
height: 200
y: 20
cascade: true
Rectangle {
Label {
x: (app_window.width / 8)
text: "FROM:"
font.pixelSize: 22
font.italic: true
color: "black"
}
Label {
y: routingMenu.height / 7
text: "Country:"
font.pixelSize: 22
font.italic: true
color: "black"
}
Label {
y: routingMenu.height / 2.5
text: "City:"
font.pixelSize: 22
font.italic: true
color: "black"
}
Label {
y: routingMenu.height / 1.6
text: "Street:"
font.pixelSize: 22
font.italic: true
color: "black"
}
Label {
y: routingMenu.height / 1.2
text: "Postal Code:"
font.pixelSize: 22
font.italic: true
color: "black"
}
} //Rectangle
Rectangle {
x: app_window.width / 2
Label {
x: (app_window.width / 4)
text: "TO:"
font.pixelSize: 22
font.italic: true
color: "black"
}
Label {
y: routingMenu.height / 7
text: "Country:"
font.pixelSize: 22
font.italic: true
color: "black"
}
Label {
y: routingMenu.height / 2.5
text: "City:"
font.pixelSize: 22
font.italic: true
color: "black"
}
Label {
y: routingMenu.height / 1.6
text: "Street:"
font.pixelSize: 22
font.italic: true
color: "black"
}
Label {
y: routingMenu.height / 1.2
text: "Postal Code:"
font.pixelSize: 22
font.italic: true
color: "black"
}
} //Rectangle
Button {
id: sendDataToItem
width: 100
height: 40
x: app_window.width / 2.7
text: "Send"
onClicked: {
//fromAddress.country: "";
//fromAddress.city: "";
//fromAddress.street: "";
//fromAddress.postalCode: "";
//toAddress.country: "";
//toAddress.city: "";
//toAddress.street: "";
//toAddress.postalCode: "";
}
} //sendDataToItem
} //Menu
I tried to use a Component, but it didn't helped me. That is code of my main.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import QtQuick.Window 2.0
import QtLocation 5.6
import QtPositioning 5.6
import "menu"
ApplicationWindow {
id: app_window
visible: true
width: maximumWidth
height: maximumHeight
title: qsTr("Navigation")
PositionSource {
active: true
onPositionChanged: {
//map_id.center = position.coordinate;
}
}
Plugin {
id: mapPlugin_
name: "osm"
}
/*Loader {
id: loadered
focus: true
source: "menu/menu.qml"
active: true
}*/
Rectangle {
id: mapRectangleID
width: 800
height: 800
x:0
y:20
Map {
id: map_
anchors.fill: parent
plugin: mapPlugin_
center: QtPositioning.coordinate(51.320729390711975,12.280097007751465)
zoomLevel: 15
MapQuickItem {
id: marker_id
coordinate: QtPositioning.coordinate(59.91, 10.75)
sourceItem: Image {
id: endPointImage
source: "assets/marker.png"
width: 100
height: 100
} //size and position of maker
anchorPoint.x: endPointImage.width / 2
anchorPoint.y: endPointImage.height
} //marker
RouteModel {
id: routeBetweenPoints
plugin: Plugin { name: "osm" }
query: RouteQuery {id: routeQuery }
Component.onCompleted: {
routeQuery.addWaypoint(QtPositioning.coordinate(51.318784,12.2773504 ));
routeQuery.addWaypoint(QtPositioning.coordinate(51.3117764,12.280909000000065 ));
//routeQuery.addWaypoint(endPointGeaocodeModel)
update();
}
} //start and end point
MapItemView {
model: routeBetweenPoints
delegate: Component {
MapRoute {
route: routeData
line.color: "red"
line.width: 10
}
} //Component
}//linie, die beide punkte verbindet
GeocodeModel{
id: endPointGeaocodeModel
plugin: Plugin { name: "osm" }
query: "Sandakerveien 116, Oslo"
onLocationsChanged: {
if (count> 0){
marker_id.coordinate = get(0).coordinate
map_id.center = get(0).coordinate
}
}
Component.onCompleted: update()
} //suche den platz mit strasse und stadt
//! [geocode0]
Address {
id: fromAddress
city: ""
country: ""
street: ""
postalCode: ""
} //fromAddress
//! [geocode0]
Address {
id: toAddress
country: ""
city: ""
street: ""
postalCode: ""
} //toAddress
} //Map
} //mapRectangleID
Button {
id: btn_close
width: 100
height: 20
text: "Close"
onClicked: {
Qt.quit();
}
}
Button {
id: btn_routing
width: 100
height: 20
x:100
text: "Routing"
onClicked: {
routingMenu.open();
}
}
Button {
id: btn_oldWay
width: 100
height: 20
x:200
text: "Old way"
onClicked: {
oldWayMenu.open();
}
}
Button {
id: rest
width: parent.width - x
height: 20
x:300
text: ""
onClicked: {
}
}
} //ApplicationWindow
I tried 2 ways to resolve the problem. One with the Loader, but I can't open my menu, and the another with example of QT which is in MapViewer Example. They import only the order and use the id of the component. But it doesn't work. I think, I do something wrong in my code, can someone tell me what I'm doing wrong or show me the right way to resolve my problem.
I think that the most important part of the code is:
Loader {
id: loadered
focus: true
source: "menu/menu.qml"
active: true
}
And then, how I'm using it:
Button {
id: btn_routing
width: 100
height: 20
x:100
text: "Routing"
onClicked: {
routingMenu.open();
}
}
By the button I'm using the component name, because I imported menu. But if I want to use the loader, I would set the visible in loader as false and then set onClicked as true. But I tried this and it didn't work.
Thanks for help
DC
The id is only valid within the .qml outside it has no meaning, for example let's say you're going to create 4 menus then if you would use the id routingMenu, which of the menus would you refer to? because that would cause confusion. So if you want to use the item loaded by Loader you must do it using the item property.
Loader {
id: loadered
focus: true
source: "menu/menu.qml"
active: true
}
// ...
Button {
id: btn_routing
width: 100
height: 20
x:100
text: "Routing"
onClicked: loadered.item.open()
}
Related
I think I'm missing something here, but I can't figure out how to set a AudioOutput device from MediaDevices audioOutputs list with the QML Components
audioOutput: AudioOutput {
id: playerOutput
device: mediaDevices.defaultAudioOutput
onDeviceChanged: {
console.log("Output device changed " + device)
}
Component.onCompleted: {
console.log(mediaDevices.audioOutputs)
}
}
MediaDevices {
id: mediaDevices
}
The 2 devices are showing:
QAudioDevice(2, Built in earpiece (IN2023), false, Output),
QAudioDevice(3, Built in speaker (IN2023), false, Output)
but I don't understand how to change it, I've tried playerOutput.setDevice() description and id but it wants a QAudioDevice (it only provides description, id and mode, the documentation for both is very vague:
This property can be used to select an output device from the
QtMultimedia::MediaDevices::audioOutputs() list.
https://doc.qt.io/qt-6/qml-qtmultimedia-mediadevices.html
https://doc.qt.io/qt-6/qml-qtmultimedia-audiooutput.html#device-prop
Any help would be appreciated!
Thanks
You can assign an object from mediaDevices.audioOutputs to the devices property of your AudioOutput.
playerOutput.device = mediaDevices.audioOutputs[index]
where index is a valid index in the audioOutputs list.
import QtQuick
import QtQuick.Window
import QtMultimedia
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello AudioOutput")
MediaDevices {
id: mediaDevices
}
MediaPlayer {
id: mediaPlayer
source: "qrc:/Test_ogg_mp3_48kbps.wav"
audioOutput: AudioOutput {
id: playerOutput
device: mediaDevices.defaultAudioOutput
onDeviceChanged: { console.log("Output device changed " + device) }
Component.onCompleted: { console.log(mediaDevices.audioOutputs) }
}
}
component MediaPlayerButton : Rectangle {
id: button
property alias text: label.text
property bool active: false
signal clicked
width: 100; height: 40; radius: 10
color: button.active ? "tomato" : "ghostwhite"
border.color: "gainsboro"
border.width: buttonMouseArea.containsMouse ? 4 : 2
Text {
id: label
anchors.centerIn: parent
font.pointSize: 18
}
MouseArea {
id: buttonMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: button.clicked()
}
}
Column {
spacing: 10
anchors.centerIn: parent
Row {
spacing: 10
MediaPlayerButton {
text: qsTr("Play")
active: mediaPlayer.playbackState === MediaPlayer.PlayingState
onClicked: { mediaPlayer.play() }
}
MediaPlayerButton {
text: qsTr("Pause")
active: mediaPlayer.playbackState === MediaPlayer.PausedState
onClicked: { mediaPlayer.pause() }
}
MediaPlayerButton {
text: qsTr("Stop")
active: mediaPlayer.playbackState === MediaPlayer.StoppedState
onClicked: { mediaPlayer.stop() }
}
}
Repeater {
model: mediaDevices.audioOutputs
Row {
spacing: 10
Rectangle {
id: r
width: 40; height: 40; radius: 20
color: mediaPlayer.audioOutput.device === mediaDevices.audioOutputs[index] ? "tomato" : "ghostwhite"
border.color: "gainsboro"
border.width: jackMouseArea.containsMouse ? 4 : 1
MouseArea {
id: jackMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: playerOutput.device = mediaDevices.audioOutputs[index]
}
}
Text {
anchors.verticalCenter: r.verticalCenter
font.pointSize: 12
text: mediaDevices.audioOutputs[index].description
}
}
}
}
}
I have an application, where I want to apply an animation to a button/ rectangle and after this executes the animation, it should display a dialog. The problem is that when the dialog.visible: true is called on onClicked, the animation is not executed. I have created a test application here are the two qml files:
main.qml
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
visible: true
FileDialogs
{
id:fileDialog
visible:false
width:800
height:800
//modality: Qt.WindowModal
z:10
}
Rectangle
{
id:rect
width:200
height:200
color:"blue"
Text
{
id:simpleText
text:"This is a button"
font.pixelSize: 20
color:"white"
width:200
height:200
}
states: [
State {
name: "PRESSED"
},
State {
name: "RELEASED"
}
]
transitions: [
Transition {
from: "PRESSED"
to: "RELEASED"
PropertyAnimation { id: selectAnim; target: rect; properties: "scale"; easing.type: Easing.OutBack; easing.amplitude: 3.0; easing.period: 1.5; from: 0; to: 1; duration: 400 }
}
]
MouseArea {
anchors.fill: parent
onPressed:
{
parent.state = "PRESSED"
}
onReleased:
{
parent.state = "RELEASED"
}
onClicked: {
fileDialog.visible=true;
}
}
}
}
FileDialogs.qml, from Qt examples
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
Item {
width: 580
height: 400
SystemPalette { id: palette }
clip: true
//! [filedialog]
FileDialog {
id: fileDialog
visible: fileDialogVisible.checked
modality: Qt.WindowModal
title: fileDialogSelectFolder.checked ? "Choose a folder" :
(fileDialogSelectMultiple.checked ? "Choose some files" : "Choose a file")
selectExisting: fileDialogSelectExisting.checked
selectMultiple: fileDialogSelectMultiple.checked
selectFolder: fileDialogSelectFolder.checked
nameFilters: [ "Image files (*.png *.jpg)", "All files (*)" ]
selectedNameFilter: "All files (*)"
sidebarVisible: fileDialogSidebarVisible.checked
onAccepted: {
console.log("Accepted: " + fileUrls)
if (fileDialogOpenFiles.checked)
for (var i = 0; i < fileUrls.length; ++i)
Qt.openUrlExternally(fileUrls[i])
}
onRejected: { console.log("Rejected") }
}
//! [filedialog]
ScrollView {
id: scrollView
anchors {
left: parent.left
right: parent.right
top: parent.top
bottom: bottomBar.top
leftMargin: 12
}
ColumnLayout {
spacing: 8
Item { Layout.preferredHeight: 4 } // padding
Label {
font.bold: true
text: "File dialog properties:"
}
CheckBox {
id: fileDialogModal
text: "Modal"
checked: true
Binding on checked { value: fileDialog.modality != Qt.NonModal }
}
CheckBox {
id: fileDialogSelectFolder
text: "Select Folder"
Binding on checked { value: fileDialog.selectFolder }
}
CheckBox {
id: fileDialogSelectExisting
text: "Select Existing Files"
checked: true
Binding on checked { value: fileDialog.selectExisting }
}
CheckBox {
id: fileDialogSelectMultiple
text: "Select Multiple Files"
Binding on checked { value: fileDialog.selectMultiple }
}
CheckBox {
id: fileDialogOpenFiles
text: "Open Files After Accepting"
}
CheckBox {
id: fileDialogSidebarVisible
text: "Show Sidebar"
checked: fileDialog.sidebarVisible
Binding on checked { value: fileDialog.sidebarVisible }
}
CheckBox {
id: fileDialogVisible
text: "Visible"
Binding on checked { value: fileDialog.visible }
}
Label {
text: "<b>current view folder:</b> " + fileDialog.folder
}
Label {
text: "<b>name filters:</b> {" + fileDialog.nameFilters + "}"
}
Label {
text: "<b>current filter:</b>" + fileDialog.selectedNameFilter
}
Label {
text: "<b>chosen files:</b> " + fileDialog.fileUrls
}
Label {
text: "<b>chosen single path:</b> " + fileDialog.fileUrl
}
}
}
Rectangle {
id: bottomBar
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
}
height: buttonRow.height * 1.2
color: Qt.darker(palette.window, 1.1)
border.color: Qt.darker(palette.window, 1.3)
Row {
id: buttonRow
spacing: 6
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 12
height: implicitHeight
width: parent.width
Button {
text: "Open"
anchors.verticalCenter: parent.verticalCenter
onClicked: fileDialog.open()
}
Button {
text: "Pictures"
tooltip: "go to my Pictures directory"
anchors.verticalCenter: parent.verticalCenter
enabled: fileDialog.shortcuts.hasOwnProperty("pictures")
onClicked: fileDialog.folder = fileDialog.shortcuts.pictures
}
Button {
text: "Home"
tooltip: "go to my home directory"
anchors.verticalCenter: parent.verticalCenter
enabled: fileDialog.shortcuts.hasOwnProperty("home")
onClicked: fileDialog.folder = fileDialog.shortcuts.home
}
}
}
}
The animation is happening. It's just the FileDialog is covering the button before you can see it animate. Release the mouse click outside the button area and you'll see the animation (this way onClicked is not triggered).
A way to show the dialog after the animation:
states: [
State {
name: "PRESSED"
},
State {
name: "RELEASED"
}
]
transitions: [
Transition {
from: "PRESSED"
to: "RELEASED"
PropertyAnimation { id: selectAnim; target: rect; properties: "scale"; easing.type: Easing.OutBack; easing.amplitude: 3.0; easing.period: 1.5; from: 0; to: 1; duration: 400 }
onRunningChanged: {
if (!running) {
fileDialog.visible = true
}
}
}
]
MouseArea {
anchors.fill: parent
onPressed:
{
parent.state = "PRESSED"
}
onClicked: {
parent.state = "RELEASED"
}
}
I am working on qml, found found an error during moving mouse wheel scrolling i.e.
"TypeError: Cannot read property 'name' of undefined".
It only appear when either mouse wheel scrolling or close the application while during execution and beginning of the application didn't show this error.
One more thing, I am getting accurate data/result whatever I want but due to this error the performance of application get affected.
Please let me know how can I get rid of this issue?
also find below example to see error.
My code is..
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
menuBar: MenuBar {
Menu {
title: qsTr("File")
MenuItem {
text: qsTr("Exit")
onTriggered: Qt.quit();
}
}
}
TableView {
anchors.fill: parent
visible: true
backgroundVisible: false
alternatingRowColors: false
sortIndicatorVisible: true
clip: true
highlightOnFocus: false
width: parent.width
height: parent.height
TableViewColumn{ role: "code" ; title: "cde" ; width: 200;
delegate: Component {
id: codeDelegate
Item{
Text {
color: "lightgray"
elide: styleData.elideMode
text: styleData.value //modelSettingData.get(styleData.row).name
font.family: "Arial"
font.pixelSize: 18
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
Text {
id: metaData
color: "red"
width: parent.width
// height: 20
anchors.bottom: parent.bottom
anchors.bottomMargin: -parent.height/1.5
font.weight: Font.ExtraLight
//elide: Text.ElideMiddle
text: "Time: " + modelSettingData.get(styleData.row).name //Error comes when this part added but I need to use it with the same form
}
}
}
}
}
TableViewColumn{ role: "name" ; title: "nme" ; width: 200
delegate: Component {
id: nameDelegate
Text {
color: "yellow"
elide: styleData.elideMode
text: styleData.value
font.family: "Arial"
font.pixelSize: 18
}
}
}
model: ListModel {
id: modelSettingData
ListElement {
name: "aaaaaaaaaa"
code: "3042666666666"
}
ListElement {
name: "bbbbbb"
code: "32235"
}
ListElement {
name: "ccccccc"
code: "32638"
}
ListElement {
name: "ddddddddddd"
code: "00000000000"
}
ListElement {
name: "eeeeeeeeeeee"
code: "111111111111"
}
ListElement {
name: "ffffffffffff"
code: "222222222222"
}
ListElement {
name: "ggggggggggggg"
code: "3333333333333"
}
ListElement {
name: "hhhhhhhhhhhhh"
code: "4444444444444"
}
ListElement {
name: "iiiiiiiiiiiii"
code: "5555555555555"
}
}
rowDelegate: Rectangle {
property bool selected : styleData.selected
width: parent.width-2
height: 100
color: styleData.selected? "black" : "black"
Rectangle {
width: parent.width
height: 1
anchors.bottom: parent.bottom
visible: parent.selected
color: "yellow"
}
}
}
}
I'm using Qt5.2 anc C++ to implement an application and need to display a list with sections similar to the example image below:
(source: ngo-hung.com)
Please note I'm not implementing a mobile app and I don't need the alphabet index on the right. Any suggestions how I can achieve this other than implementing a QTreeView?
Thanks.
ListView in QML has built-in support for sections. In the following example, I have a ListModel where the section is defined via a "sec" role. The ListModel defines a section delegate as well as a contact delegate:
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Page {
id: page
header: Frame {
background: Rectangle {
color: "red"
}
RowLayout {
width: parent.width
Item {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
Button {
anchors.centerIn: parent
background: Item {}
icon.source: "https://raw.githubusercontent.com/Esri/calcite-ui-icons/master/icons/address-book-32.svg"
icon.width: 32
icon.height: 32
icon.color: "white"
}
}
Text {
Layout.fillWidth: true
text: qsTr("All Contacts")
color: "white"
}
}
}
anchors.fill: parent
ListView {
anchors.fill: parent
model: contacts
delegate: Frame {
width: ListView.view.width
RowLayout {
width: parent.width
Item {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
Button {
anchors.centerIn: parent
background: Item {}
icon.source: "https://raw.githubusercontent.com/Esri/calcite-ui-icons/master/icons/user-32.svg"
icon.width: 32
icon.height: 32
icon.color: "green"
}
}
ColumnLayout {
Layout.fillWidth: true
Text {
Layout.fillWidth: true
text: fn
}
Text {
Layout.fillWidth: true
text: qsTr("Full name: %1 %2").arg(fn).arg(sn)
}
}
}
}
section.property: "sec"
section.delegate: Frame {
width: ListView.view.width
background: Rectangle {
color: "lightsteelblue"
}
Text {
text: section
color: "white"
}
}
}
ListModel {
id: contacts
ListElement {
sec: "B"; fn: "Branda"; sn: "Respass"
}
ListElement {
sec: "C"; fn: "Chana"; sn: "Hollin"
}
ListElement {
sec: "D"; fn: "Delisa"; sn: "Deak"
}
ListElement {
sec: "D"; fn: "Demetrius"; sn: "Zona"
}
ListElement {
sec: "D"; fn: "Dwain"; sn: "Mark"
}
}
}
You can Try it Online!
Here's the code:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Window 2.1
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.1
Window {
id: window
/* Interface */
Rectangle {
id: dataView
anchors.topMargin: 10
height: 30 * model.count
width: 600
radius: 5
border.color: "#333"
border.width: 1
color: "black"
opacity: 0.6
clip: true
ListView {
anchors.fill: parent
anchors.topMargin: 7
model: model
delegate: delegate
interactive: false
spacing: 6
highlight: Rectangle {
color: "#333"
border.width: 1
border.color: "red"
}
onHighlightItemChanged: {
console.debug(1);
}
}
}
/* Model */
ListModel {
id: model
ListElement {
name: "Google Chrome"
icon: ""
}
ListElement {
name: "Google Chrome"
icon: ""
}
ListElement {
name: "Google Chrome"
icon: ""
}
}
Component {
id: delegate
Rectangle {
id: wrapper
height: 24
anchors.topMargin: 7
anchors.bottomMargin: 7
Row {
anchors.fill: parent
spacing: 0
Image {
id: delegateIcon
fillMode: Image.Stretch
source: icon
width: 24
height: 24
}
Text {
text: name
font.pixelSize: 12
font.family: "Segoe UI"
color: "#fff"
}
}
}
}
}
The problem is described in the headline: when I hover an item with a mouse, nothing happens. Moreover, onHighlightItemChanged only emits at the start of the application.
What am I doing wrong?
1) You need to add a width to your delegate
id: wrapper
height: 24
becomes
id: wrapper
height: 24
width: parent.width // or 100
2) You need to trigger the action "click -> item changed", by adding this
MouseArea {
anchors.fill: parent
z: 1
onClicked:
{
list.currentIndex = index
}
}
under the delegate's Row { }
Note: onHighlightItemChanged: isn't doing what you think (it checks if the delegate component is changed, as if you have 2 possible delegates). This is better:
onCurrentIndexChanged: {
console.debug("New index : "+ currentIndex);
}