My custom ComboBox works is correctly, but I do not understand how to up popup with list of element above of combobox.
ComboBox {
id: pointsPositionComboBox
anchors.fill: parent
displayText: qsTr("Position point")
model: map.pointPositionModel
textRole: "name"
delegate: Row {
Rectangle {
id: delegateRect
width: pointsPositionRect.width - removePointRect.width
height: pointsPositionRect.height
color: {
if (!delegateRectMouseArea.containsMouse)
return "#25263C"
else if (delegateRectMouseArea.containsMouse
&& !delegateRectMouseArea.pressed) {
return "#5F8C6D"
} else if (delegateRectMouseArea.containsMouse
&& delegateRectMouseArea.pressed) {
return "#73AB84"
}
}
Text {
text: model.name
color: "white"
width: parent.width - removePointItem.width
font.pixelSize: pointsPositionComboBox.font.pixelSize
anchors.topMargin: pointsPositionRect.height / 3
anchors.left: parent.left
anchors.leftMargin: 5
}
MouseArea {
id: delegateRectMouseArea
anchors.fill: delegateRect
hoverEnabled: true
acceptedButtons: Qt.LeftButton
onClicked: {
if (hasUserMenuProperty.hasUserMenu()
&& !globalUserManager.hasAccessToPrivilege("controlMap"))
return
const latitude = model.position.latitude
const longitude = model.position.longitude
map.center.latitude = latitude
map.center.longitude = longitude
map.zoomLevel = model.zoomLevel
globalMapProperty.bearing = model.bearing
pointsPositionComboBox.popup.close()
}
}
}
Rectangle {
id: removePointRect
width: 30
height: 30
z: pointsPositionComboBox.z + 1
color: {
if (!removePointItemMouseArea.containsMouse)
return "#25263C"
else if (removePointItemMouseArea.containsMouse
&& !removePointItemMouseArea.pressed) {
return "#73A081"
} else if (removePointItemMouseArea.containsMouse
&& removePointItemMouseArea.pressed) {
return "#52785E"
}
}
Image {
id: removePointItem
anchors.centerIn: parent
source: removePointItemMouseArea.containsMouse ? "qrc:/icons/compass/remove_point_en.svg"
: "qrc:/icons/compass/remove_point_dis.svg"
}
MouseArea {
id: removePointItemMouseArea
anchors.fill: removePointRect
hoverEnabled: true
acceptedButtons: Qt.LeftButton
onClicked: {
if (hasUserMenuProperty.hasUserMenu()
&& !globalUserManager.hasAccessToPrivilege("controlMap"))
return
map.pointPositionModel.remove(map.pointPositionModel.index(index, 0))
}
}
}
}
}
Component.onCompleted: {
pointsPositionComboBox.popup.contentItem.implicitHeight = Qt.binding(function () {
// Делаем отображение только 10 элементов (остальные скроллом только)
return Math.min(pointsPositionRect.height * 10,
pointsPositionComboBox.popup.contentItem.contentHeight)
})
}
How to display a list of combo box elements from the top, and not from the bottom as in the photo?
P.s. I set implicitHeight for displaying element of combobox in Component.onCompleted
P.s.2 Now it looks like picture:
I've used the implicitHeight of the Popup to set its y property. Have a look at the source below. The default behavior of the Popup is when ever it fits below it will open up below, if there is not enough space below it will open above the ComboBox. The following code is a tweaked version of the Customizing ComboBox example from the Qt documentation.
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
width: 400
height: 300
Row {
anchors.centerIn: parent
ComboBox {
id: control
model: ["First", "Second", "Third"]
delegate: ItemDelegate {
width: control.width
contentItem: Text {
text: modelData
color: "#21be2b"
font: control.font
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
highlighted: control.highlightedIndex === index
}
indicator: Canvas {
id: canvas
x: control.width - width - control.rightPadding
y: control.topPadding + (control.availableHeight - height) / 2
width: 12
height: 8
contextType: "2d"
Connections {
target: control
function onPressedChanged() { canvas.requestPaint(); }
}
onPaint: {
context.reset();
context.moveTo(0, 0);
context.lineTo(width, 0);
context.lineTo(width / 2, height);
context.closePath();
context.fillStyle = control.pressed ? "#17a81a" : "#21be2b";
context.fill();
}
}
contentItem: Text {
leftPadding: 10
rightPadding: control.indicator.width + control.spacing
text: control.displayText
font: control.font
color: control.pressed ? "#17a81a" : "#21be2b"
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 120
implicitHeight: 40
border.color: control.pressed ? "#17a81a" : "#21be2b"
border.width: control.visualFocus ? 2 : 1
radius: 2
}
popup: Popup {
y: myCheckBox.checked ? -implicitHeight + 1 : control.height - 1
width: control.width
implicitHeight: contentItem.implicitHeight
padding: 1
contentItem: ListView {
clip: true
implicitHeight: contentHeight
model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
}
background: Rectangle {
border.color: "#21be2b"
radius: 2
}
}
}
CheckBox {
id: myCheckBox
text: qsTr("above")
}
}
}
I have to take 4 continues pictures using the webcamera in QML i can take only one picture after that
I get an error from the QML debugger which states "Camera not ready for capture" how do i get the camera to be in ready state after the first capture this is the code i have tried
even if i set the ready state to true: it does not seem to be working? is there an easy way to get my way around this?
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle{
width: parent.width
height: parent.height
ColumnLayout{
width: parent.width;height: parent.height
spacing: 15;
Camera{
id:cam
captureMode: Camera.CaptureStillImage
imageCapture {
onImageCaptured: {
ready:true
console.log(ready)
}
}
}
VideoOutput{
id:vid1
source: cam
height:parent.height
width: 800
Layout.fillWidth: true
Layout.fillHeight: true
}
Rectangle{
id:rect1
width: 100
height: 30
Layout.fillWidth: true
Layout.alignment:bottom
color: "#365688"
Text {
id: text1
anchors.centerIn: parent
text:"capture"
font.pointSize: 10
}
MouseArea{
anchors.fill:parent
onClicked: {
console.log("clicked");
for(var i=0;i<=3;i++){
cam.start()
cam.imageCapture.captureToLocation("C:/Users/vinay/Documents")
console.log(cam.cameraStatus)
}
}
}
}
}
}
}
If I have the following:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow {
title: qsTr("Hello World")
width: 800
height: 700
visible: true
property var myArray: [1, 2, 3, 4, 5, 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
menuBar: MenuBar {
Menu {
title: qsTr("&File")
MenuItem {
text: qsTr("&Open")
onTriggered: messageDialog.show(qsTr("Open action triggered"));
}
MenuItem {
text: qsTr("E&xit")
onTriggered: Qt.quit();
}
}
}
Rectangle {
id: myButton
anchors.top: parent.top
anchors.topMargin: 5
color: "yellow"
width: 100
height: 25
radius: 3
anchors.horizontalCenter: parent.horizontalCenter
Text {
text: "Clear Selection"
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
myListView.currentIndex = -1
}
}
}
ListView {
id: myListView
width: 300
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: myButton.bottom
anchors.topMargin: 5
anchors.bottom: parent.bottom
currentIndex: -1
//highlightFollowsCurrentItem: false
highlight: Rectangle {
color: "pink"
radius: 3
width: parent.width - 10
height: 25
//y: myListView.currentItem.y
anchors.horizontalCenter: parent.horizontalCenter
}
clip: true
model: myArray
delegate: Rectangle {
width: parent.width - 10
height: 25
color: "transparent"
border.color: "cyan"
anchors.horizontalCenter: parent.horizontalCenter
Text {
text: myArray[index]
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.fill: parent
}
MouseArea {
anchors.fill: parent
onClicked: myListView.currentIndex = index
}
}
}
MessageDialog {
id: messageDialog
title: qsTr("May I have your attention, please?")
function show(caption) {
messageDialog.text = caption;
messageDialog.open();
}
}
}
When clicking the Clear Selection button I receive the following:
qrc:/main.qml:67: TypeError: Cannot read property of null
qrc:/main.qml:64: TypeError: Cannot read property of null
How can I clear the selection without getting the error? It doesn't appear to crash the application but I have a list view that changes based on another list view selection and the error occurs several times, cluttering up the debug output in Qt Creator. I have noticed this in Qt 5.4 and 5.5
The documentation for ListView says:
An instance of the highlight component is created for each list. The geometry of the resulting component instance is managed by the list so as to stay with the current item, unless the highlightFollowsCurrentItem property is false.
So you don't need to try to manage the position of the highlight item yourself. If you want to position the highlight, create an intermediate parent item instead:
highlight: Item {
Rectangle {
color: "pink"
radius: 3
width: parent.width - 10
height: 25
anchors.horizontalCenter: parent.horizontalCenter
}
}
As for why it happens, it's likely because the highlight item is reparented, leaving it in a state where its parent property is null. You can test this out with the following code:
anchors.horizontalCenter: { print(parent); parent.horizontalCenter }
The problem in general is that if you have a foo, which is supposed to have a bar, then you reference it as foo.bar, however, if foo was not properly initialized, then it cannot have a bar, since it does not exist (yet). In your case it seems that parent is not properly initialized, so it does not have a width and horizontalCenter (in the delegate, maybe), respectively. The solution is to initialize properly the object whose members are to be used, in our case, parent.
I had asked this question over on the Qt forum (https://forum.qt.io/topic/62328/clearing-a-qml-listview-selection) as well, but stack was quicker with a response. Checking the parent value works:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow {
title: qsTr("Hello World")
width: 800
height: 700
visible: true
property int myMargin: 5
menuBar: MenuBar {
Menu {
title: qsTr("&File")
MenuItem {
text: qsTr("&Open")
onTriggered: messageDialog.show(qsTr("Open action triggered"));
}
MenuItem {
text: qsTr("E&xit")
onTriggered: Qt.quit();
}
}
}
Rectangle {
id: myButton
anchors.top: parent.top
anchors.topMargin: myMargin
color: "yellow"
width: 100
height: 25
radius: 3
anchors.horizontalCenter: parent.horizontalCenter
Text {
text: "Clear Selection"
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
myListView.currentIndex = -1
}
}
}
Rectangle {
width: 300
anchors.top: myButton.bottom
anchors.topMargin: myMargin
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
ListView {
id: myListView
anchors.fill: parent
currentIndex: -1
spacing: 3
highlightMoveDuration: 25
highlight: Rectangle {
width: parent ? parent.width - 10 : 0
height: parent ? 25 : 0
color: "pink"
radius: 3
anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
}
clip: true
model: ListModel {
id: myArray
Component.onCompleted: {
for (var i = 1; i < 46; i++)
append({number: i})
}
}
delegate: Rectangle {
width: parent ? parent.width - 10 : 0
height: parent ? 25 : 0
color: "transparent"
border.color: "cyan"
anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
Text {
text: number
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.fill: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
myListView.currentIndex = index
}
}
}
}
}
MessageDialog {
id: messageDialog
title: qsTr("May I have your attention, please?")
function show(caption) {
messageDialog.text = caption;
messageDialog.open();
}
}
}
I have to implement TreeView in qml. Basically because each subtree is just TreeView itself, i want to use TreeView component in TreeView definition (this is that Repeater on the end).
This is part of code where i reference the component i am defining.
You can see that rootDelegate is actually id of the Component.
Problem is Qt gives error Unable to assign QQuickRow to QQmlComponent
Repeater {
model: childrens
delegate: rootDelegate
}
TreeView.qml
import QtQuick 2.0
Component {
id: rootDelegate
Column {
Row {
id: itemControl
spacing: 2
Rectangle {
anchors.verticalCenter: parent.verticalCenter
gradient: Gradient {
GradientStop { position: 0.0; color: "#EEEEEE" }
GradientStop { position: 1.0; color: "#404040" }
}
width: openChar.implicitWidth
height: openChar.implicitHeight - 6
radius: 3
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}
Text {
id: openChar
text: "+"
color: "black"
anchors.centerIn: parent
}
}
Rectangle {
height: 1
color: "#A0A0A0"
width: 10
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: model.text
color: "white"
}
}
Repeater {
model: childrens
delegate: rootDelegate
}
}
}
You are trying to use a Сomponent recursively in itself, it is not allowed in Qml
In traditional Qt (QWidget) I have one QMainWindow and some dynamically created QWidgets with the content and I change them that one was seen in main windows. What are the ways of achieving when I have couple qml files and I wants to be able to switch between them when eg clicking a button.
There are at least 3 options for solving this problem:
You can use the ready for this purpose component StackView. The point is that you will create 2 components at once and you'll be able to change them by clicking on the button.
Example:
import QtQuick 2.12
import QtQuick.Controls 2.5
ApplicationWindow {
id: window
visible: true
width: 640
height: 480
title: qsTr("Stack")
header: ToolBar {
contentHeight: toolButton.implicitHeight
ToolButton {
id: toolButton
text: stackView.depth > 1 ? "\u25C0" : "\u2630"
font.pixelSize: Qt.application.font.pixelSize * 1.6
onClicked: {
if (stackView.depth > 1) {
stackView.pop()
} else {
drawer.open()
}
}
}
Label {
text: stackView.currentItem.title
anchors.centerIn: parent
}
}
Drawer {
id: drawer
width: window.width * 0.66
height: window.height
Column {
anchors.fill: parent
ItemDelegate {
text: qsTr("Page 1")
width: parent.width
onClicked: {
stackView.push("Page1Form.qml")
drawer.close()
}
}
ItemDelegate {
text: qsTr("Page 2")
width: parent.width
onClicked: {
stackView.push("Page2Form.qml")
drawer.close()
}
}
}
}
StackView {
id: stackView
initialItem: "HomeForm.qml"
anchors.fill: parent
}
}
Use the Loader here you will dynamically load files during execution, the disadvantage of this method is that if you switch often, it will be time consuming.
Example:
import QtQuick 2.0
Item {
width: 200; height: 200
Loader { id: pageLoader }
MouseArea {
anchors.fill: parent
onClicked: pageLoader.source = "Page1.qml"
}
}
You can create a class in C++ that will be given to an already initialized QML object to an empty qml form. thus, mono place individual components into libraries and use them as plugins (use qqmlcomponent).
I would use a simple Loader, with a button that when is clicked, changes the source file of the Loader. Like so :
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
Window {
id: root
Rectangle {
id: page_main
color: "#202020"
anchors.fill : parent
Button {
id: button_page_1
width: 105
text: qsTr("Page 1")
anchors {
left: parent.left
top: parent.top
leftMargin: 6
topMargin: 0
}
checkable: true
onClicked: {
if (loader_main.source == "/page_1.qml") {
loader_main.source = ""
} else {
loader_main.source = "/page_1.qml"
button_page_2.checked = false
button_page_3.checked = false
}
}
}
Button {
id: button_page_2
width: 105
text: qsTr("Page 2")
anchors {
left: button_auto.right
top: parent.top
leftMargin: 6
topMargin: 0
}
checkable: true
onClicked: {
if (loader_main.source == "/page_2.qml") {
loader_main.source = ""
} else {
loader_main.source = "/page_2.qml"
button_page_1.checked = false
button_page_3.checked = false
}
}
}
Button {
id: button_page_3
width: 105
text: qsTr("Page 3")
anchors {
left: button_manual.right
top: parent.top
leftMargin: 6
topMargin: 0
}
checkable: true
onClicked: {
if (loader_main.source == "/page_page_3.qml") {
loader_main.source = ""
} else {
loader_main.source = "/page_page_3.qml"
button_page_1.checked = false
button_page_2.checked = false
}
}
}
}
Loader {
id: loader_main
y: 60
visible: true
anchors {
top: parent.top
bottom: parent.bottom
right: parent.right
left: parent.left
topMargin: 48
bottomMargin: 0
leftMargin: 0
rightMargin: 0
}
}
}