I have the following qml file:
import QtQuick 1.0
Component{
Column{
id: interHeader;
Item{
id:interItem
height: 300
width: 200
Text{
id:title
text:"Text"
anchors.centerIn: parent
font.bold: true
elide:"ElideRight"
color: "Black"
}
}
Item {
width: parent.width
height: 100
//onClick event
MouseArea {
anchors.fill: parent
onClicked:{
console.log("Ok");
}
}
}
}
}
The problem is that I need to assign some KeyNavigation to the interItem.
I want to access the interItem from another qml file.
How can this be done?
There really is no benefit of using Component in a completely separate QML file. Remove Component and name your Qml file with a capital letter - e.g. InterHeader
Then define a property under your root item. For example:
import QtQuick 1.0
Item {
id: interHeader
property variant keyActionUp
Keys.onUpPressed: keyActionUp
}
OR
You can use the Connections function to execute callbacks for signals from interHeader.
http://doc.qt.nokia.com/4.7-snapshot/qml-connections.html
Related
We have a working code
Page {
header: Item {}
}
I need to create a new template component in which I can then put the necessary components, just as we write our component in the property of the header, that is, I'm interested in how to make my analog header template.
Found an answer.
Template file Some.qml:
import QtQuick 2.0
Item {
width: 500
height: 500
property alias content: column.children
Column {
id: column
anchors.fill: parent
}
}
and use it
import QtQuick 2.0
Some {
content: Rectangle {
width: parent.width
height: 100
color: "red"
}
}
I am making a music player application. i have a DownRect which has a slider and a playSection which has a button. this button has a audio. when button is clicked audio is played and i want the slider to set it's value by the audio duration. (the button is add dynamically from ButtonD.qml file). what i want to do is to connect DownRect's slider to playSection's button.
//DownRect.qml
Rectangle{
id: downRectangle
width: parent.width
height: parent.height
x:0
y:750
color: "#c62828"
smooth: true
Slider{
id: sliderDownRect
x: 300
y: 25
width: 650
from: 0
// to: play.duration
stepSize: 100
value: 0
Material.accent : Material.background
Material.foreground: Material.background
onValueChanged:{
}
}
}
and here is the ButtonD.qml file which i'd like to connect to DownRect.qml
//ButtonD.qml
Button{
id: buttonD
width:900
height: 46
flat: true
Audio{
id: playing
}
}
You make sure that the duration (and other relevant properties of Audio) are exposed in ButtonD.qml, e.g. by adding aliases like such:
Button {
id: buttonD
property alias duration: playing.duration
...
}
The same goes for the Slider's value.
Rectangle {
id: downRectangle
property alias duration: sliderDownRect.to
...
}
In the file that instantiates both, you use Binding-objects to create a bidirectional binding between the both. Those Binding-objects excell at working with dynamically instantiated objects.
Basically, if you'd include the files into one file, this should look something like this:
main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtMultimedia 5.5
ApplicationWindow {
id: myWindow
visible: true
width: 600
height: 600
color: 'white'
property Item dynamicallyCreatedItem
Button {
x: 102
text: 'create'
onClicked: {
dynamicallyCreatedItem = Qt.createComponent('AudioButton.qml').createObject(myWindow.contentItem)
}
}
DownRect {
y: 50
id: rect
}
Binding {
target: rect
property: 'maxValue'
value: dynamicallyCreatedItem ? dynamicallyCreatedItem.duration : 0
when: dynamicallyCreatedItem
}
Binding {
target: rect
property: 'value'
value: dynamicallyCreatedItem ? dynamicallyCreatedItem.position : 0
when: dynamicallyCreatedItem
}
}
AudioButton.qml
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtMultimedia 5.5
Button {
id: audioButton
onClicked: audio.play()
property alias duration: audio.duration
property alias position: audio.position
Audio {
id: audio
source: 'airhorn.wav'
}
}
DownRect.qml
import QtQuick 2.0
import QtQuick.Controls 2.0
Rectangle {
id: rect
width: parent.width
height: 50
property alias value: slider.value
property alias maxValue: slider.to
Slider {
id: slider
anchors.fill: parent
}
}
I am trying to modify Gallery example. I want to add Button under TabView. So, I put TabView and Button into ColumnLayout, here is code:
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Window 2.0
Window {
visible: true
title: "settings"
width: 600
height: 400
ColumnLayout{
anchors.fill: parent
TabView {
anchors.right: parent.right
anchors.left: parent.left
Tab {
title: "Controls"
Controls { }
}
Tab {
title: "Itemviews"
Controls { }
}
Tab {
title: "Styles"
Controls { }
}
Tab {
title: "Layouts"
Controls { }
}
}
RowLayout{
anchors.right: parent.right
anchors.left: parent.left
Button{
text: "ok"
}
}
}
}
However, when I resize window okButton stands under tab controls. How should I fix code?
When you have defined a Layout, each element added has access to specific properties related to the layout itself. These properties are useful to position the element inside the space covered from the layout. Confront what is described here.
Hence, you should modify the ColumnLayout like this:
ColumnLayout {
anchors.fill: parent
TabView {
id:frame
enabled: enabledCheck.checked
tabPosition: controlPage.item ? controlPage.item.tabPosition : Qt.TopEdge
Layout.fillHeight: true // fill the available space vertically
Layout.fillWidth: true // fill the available space horizontally
Layout.row: 0 // item in the first row of the column
anchors.margins: Qt.platform.os === "osx" ? 12 : 2
Tab {
id: controlPage
title: "Controls"
Controls { }
}
Tab {
title: "Itemviews"
ModelView { }
}
Tab {
title: "Styles"
Styles { anchors.fill: parent }
}
Tab {
title: "Layouts"
Layouts { anchors.fill:parent }
}
}
Button {
text: "ok"
Layout.row: 1 // item in the second row of the column
Layout.alignment: Qt.AlignCenter // simple center the button in its spatial slot
}
}
You don't need a RowLayout for the button. It should be placed in the second row of the ColumnLayout you have defined, since it is a simple component. A sub-layout could be useful in case of multiple elements on the same row, e.g. two or more buttons.
Note also that anchoring is just used for the ColumnLayout to "stretch" and fit the window. All the other operations are executed via the layout properties. For general rules take a look at this other article.
I have a QML singleton for use in styling defined as follows:
pragma Singleton
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
QtObject {
property ProgressBarStyle progressBarErrorStyle: ProgressBarStyle {
background: Rectangle {
radius: 2
color: "lightgray"
border.color: "gray"
border.width: 1
implicitWidth: 200
implicitHeight: 20
}
progress: Rectangle {
color: "orangered"
border.color: "red"
}
}
}
I'm able to import the object and use it, however progressBarErrorStyle is always given the type ProgressBarStyle_QMLTYPE_17. If I change it to a Rectangle, then it is correctly typed as QQuickRectangle.
The QtQuick.Controls.Styles import defines ProgressBarStyle, and in QtCreator I'm not getting any syntax errors... so why is my object given the wrong type at runtime?
You should use Component as the property type:
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
Rectangle {
property Component progressBarErrorStyle: ProgressBarStyle {
background: Rectangle {
radius: 2
color: "lightgray"
border.color: "gray"
border.width: 1
implicitWidth: 200
implicitHeight: 20
}
progress: Rectangle {
color: "orangered"
border.color: "red"
}
}
ProgressBar {
id: progressBar
NumberAnimation {
target: progressBar
property: "value"
to: 1
running: true
duration: 2000
}
style: progressBarErrorStyle
}
}
The components for styles are used in Loader items internally, which create instances of the components when they need to, just like delegates in Qt Quick's ListView, for example.
I'm trying to highlight the currently selected item in a ListView. Below is the code I'm using; for some reason, while a similar code works perfectly in another ListView of this application, here the SelectedRectangle item is never displayed, althought the selected item changes when it should.
Rectangle {
id: deviceTree
width: (window.width * 2) / 3
height: 400
border {
width: 2
color: "black"
}
ListView {
id: deviceTreeView
model: deviceTreeModel
delegate: deviceTreeDelegate
highlight: SelectionRectangle {}
anchors.fill: parent
anchors.margins: 6
}
Component {
id: deviceTreeDelegate
Rectangle {
border.color: "#CCCCCC"
width: deviceTree.width
height: 30
smooth: true
radius: 2
MouseArea {
anchors.fill: parent
onClicked: { deviceTreeView.currentIndex = index; window.selectedDeviceChanged(deviceName) }
}
}
}
}
SelectedRectangle.qml
Rectangle
{
id: selectionRectangle
color: "lightsteelblue"
smooth: true
radius: 5
}
SOLUTION: The rectangle in deviceTreeDelegate was by default white and overlapped the selection rectangle. Using the property it's set as trasparent so that the selection can be seen.
This is due to the default Rectangle color being white and the highlight being stacked under the delegate. Setting the Rectangle color to "transparent" will allow the highlight to be visible through the delegate.
Your code gets two mistakes :
The component for the highlight property. The name of the type of the component is the same than the name of the QML file where it is defined. You defined it in a file named SelectedRectangle.qml so you have to write highlight: SelectionRectangle {} in your main QML file
The type of the highlight member is Component. So the component that you use for this member should have got a type which inherits Component. Or you use a QML component that inherits Rectangle and Rectangle does not inherit Component. You should enclose your SelectedRectangle in a Component object, just like you did for the delegate.
Finally, you should write something like this for your highlight component :
highlight: Component {
SelectedRectangle {}
}