Following is the sample Button QML code that I found in google:
Button {
id: myButton
text: "btnTxt";
function buttonClick()
{
console.log("Button "+ myButton.text +" is clicked!")
}
MouseArea {
id: myMouseId
anchors.fill: parent
onClicked:
{
myButton.buttonClick();
}
}
style: ButtonStyle {
background:
Rectangle {
color: myMouseId.pressed ? "#336699" : "#0099FF";
radius: 1;
}
}
}
And I am using the following imports:
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.4
But, Qt threw the error:
Invalid property assignment: "pressed" is a read-only property
Also, is there an complete example for this basic type? I couldn't find in the doc how to address the above condition.
Related
I am trying to access items that are in a Repeater, using JavaScript. This works as long as everything is in a single QML file. I understand that, when I split things into two files, the id of the Repeater moves out of the scope of my script.
What I don't understand is how I best solve this problem, since I cannot export the id as property.
Here is a MWE with two files:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.2
Window {
id: root
visible: true
width: 640
height: 480
ColumnLayout {
Mwe2 {}
Button {
text: "Test"
onClicked: {
console.log("Clicked");
rect.itemAt(1).color = 'yellow'; # <- out of scope
}
}
}
}
File Mwe2.qml
import QtQuick 2.9
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.2
RowLayout {
spacing: 2
Repeater {
id: rect
model: 3
Rectangle {
color: 'red'
width: 50
height: 20
}
}
}
As you indicate, the ids have the scope of the qml file, so if you want to access those elements you must expose it through a property, function, etc. of the top level of the qml. In this case for simplicity I will use an alias.
import QtQuick 2.9
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.2
RowLayout {
property alias repeater: rect
spacing: 2
Repeater {
id: rect
model: 3
Rectangle {
color: 'red'
width: 50
height: 20
}
}
}
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.2
Window {
id: root
visible: true
width: 640
height: 480
ColumnLayout {
Mwe2 {
id: mwe2
}
Button {
text: "Test"
onClicked: {
console.log("Clicked")
mwe2.repeater.itemAt(1).color = "yellow"
}
}
}
}
Is it possible to pick between different types of sub-components dynamically (during instantiation)?
For example, some pseudocode (using Qt 5.9):
//MyComp.qml
import QtQuick 2.9
import QtQuick.Layouts 1.3
Item {
property bool useLayout: true
//Here I want to allow the user to choose
//whether a ColumnLayout or Column is used
//(e.g., by means of the useLayout property)
ColumnLayout { //Or Column
...
}
...
}
//main.qml
import QtQuick 2.9
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.9
ApplicationWindow {
width: 640
height: 480
...
MyComp {
id: a
useLayout: false
...
}
}
I don't think there is a way to do exactly what you want, without a lot of javascript. The cleanest way to do this, that I can think of would be the following.
You could make the ColumnLayout invisible and set the Column as the parent of its children with something like this:
//MyComp.qml
import QtQuick 2.9
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.5
Item {
property bool useLayout: true
ColumnLayout {
id: columnLayout
visible: useLayout
Component.onCompleted: {
if (!useLayout) {
butt1.parent = column;
butt2.parent = column;
butt3.parent = column;
}
}
Button {
id: butt1
text: "butt 1"
}
Button {
id: butt2
text: "butt 2"
}
Button {
id: butt3
text: "butt 3"
}
}
Column {
id: column
visible: !useLayout
}
}
I'm working on a DatePicker control for QtQuick.Controls 2.0 I have problem on drawing popup calendar over other page items. does anyone help me on this ?
Component Screenshot
My DatePicker source code:
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Controls 1.4 as OldControls
Rectangle {
id: root
width: childrenRect.width
height: childrenRect.height
clip: true
property bool expanded: false
property bool enabled: true
property alias selectedDate: cal.selectedDate
MouseArea {
height: expanded ? txt.height + cal.height : txt.height
width: expanded ? Math.max(txt.width, cal.width) : txt.width
hoverEnabled: true
enabled: root.enabled
onHoveredChanged: {
expanded = root.enabled && containsMouse
}
TextField {
id: txt
enabled: root.enabled
text: cal.selectedDate
inputMask: "0000-00-00"
}
OldControls.Calendar {
id: cal
anchors.top: txt.bottom
anchors.left: txt.left
visible: expanded
}
}
}
and here is my DatePicker usage in page:
import QtQuick 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls 2.2
import "./Components"
Item {
anchors.fill: parent
GridLayout {
columns: 2
Text { text: qsTr("Date Filter: ") }
DatePicker {}
Text { text: qsTr("name filter: ") }
TextField {}
}
}
I'm trying to put the business logic in Main.qml and the UI in MainForm.ui.qml but I can't connect both by widget id.
MainForm.ui.qml:
import QtQuick 2.8
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
Page {
id: page
header: TabBar { ... }
StackLayout {
id: stack
Pane {
Flow {
TextField {
id: theText
}
property alias sendBtn: sendBtn
Button {
id: sendBtn
}
}
}
}
}
Main.qml:
import QtQuick 2.8
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
MainForm {
anchors.fill: parent
sendBtn {
onClicked: backend.sendTextToServer( theText.text )
}
}
}
Qt Creator says : Invalid property name "sendBtn" (M16)
Running failed with the following messages:
QQmlApplicationEngine failed to load component
qrc:/Main.qml:12 Cannot assign to non-existent property "sendBtn"
when you put property alias sendBtn: sendBtn inside Pane is interpreted as being a Pane property so you can not access it that way, it is correct to place it in the context of Page.
import QtQuick 2.8
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
Page {
id: page
property alias sendBtn: sendBtn
property alias theText: theText
header: TabBar { ... }
StackLayout {
id: stack
Pane {
Flow {
TextField {
id: theText
}
Button {
id: sendBtn
}
}
}
}
}
I want to use some qml file(main.qml) but before that I need to get some authentication info from user(login, pass). So I want to do this in the second window(login.qml). I saw Qt.createComponent for opening second qml file, but I can't get any information from this type of window.
So how can I use some information from the second window in the first window?
Or how can I dynamically load these items(main.qml, login.qml) in the parent qml file?
So how can I use some information from the second window in the first
window?
This is just one way of doing it:
main.qml
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
ApplicationWindow {
width: 400
height: 400
visible: true
ColumnLayout {
id: logItems
height: 200
Button {
id: loginButton
onClicked: loginForm.visible = true
text: "Log in"
}
Login {
anchors.top: loginButton.bottom
id: loginForm
visible: false
onLoginInfo: {
logInfo.text = "User:" + user + " password: " + password
}
}
}
Text {
id: logInfo
anchors.top : logItems.bottom
}
}
Login.qml
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
Item {
signal loginInfo(string user, string password)
ColumnLayout {
RowLayout {
TextField {
id: user
}
TextField {
id: password
}
}
Button {
text: "Submit"
onClicked: loginInfo(user.text, password.text)
}
}
}
How can I dynamically load QML items from separate files/resources in
another QML file?
Qt.CreateComponent allows you to use JavaScript to dynamically create and use QML code from other files.