UI slider: error: Invalid attached object assignment - qt

I try to add tooltip to QML slider like this:
import QtQuick 2.9
import QtQuick.Controls 2.4
import QtQuick.Controls.Material 2.4
import Qt.labs.settings 1.0
import QtQuick.Layouts 1.3
// ...
Slider {
ToolTip: qsTr("This slider likes doing ...") // Invalid attached object assignment
// ...
}
// ...
But I'm receiving this error:
Invalid attached object assignment
What am I missing?

Error got resolved by using ToolTip this way:
Slider {
ToolTip {
text: qsTr("This slider likes doing ...")
visible: parent.hovered
delay: 1000
}
}

Related

QtQuickControls FileDialog Automation

I'm trying to automate picking a file in QML in a QtQuick Controls FileDialog. How can I invoke FileDialog's accept with a specific fileUrl when the fileUrl property is read only?
The current attempt involves calling filedialog.clearSelection, filedialog.addSelection and finally filedialog.accept. clearSelection and addSelection are not documented but can be found in https://github.com/qt/qtquickcontrols/blob/dev/src/dialogs/qquickfiledialog.cpp (Assuming Qt has used a DefaultFileDialog as this can be system dependent)
However clearSelection seems to only work sporadically, having no affect if the same FileDialog has been used manually, hence the addSelection fails to set fileUrl.
The following is a QML file (loaded as a basic project within QtCreator) demonstrates this. with a manual file dialog open button and an automatic one:
import QtQuick 2.9
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.4
import QtQuick.Dialogs 1.3
Window {
visible: true;width: 200;height:200
FileDialog {id: filedialog; onAccepted: console.log("File Dialog Accepted: ", fileUrl, fileUrls);}
Row {
Button {text: "manual"; onClicked: filedialog.open()}
Button {
text: "auto_qml"
onClicked: {
console.log("Current selection:", filedialog.fileUrl, filedialog.fileUrls)
filedialog.clearSelection();
console.log("cleared selection:", filedialog.fileUrl, filedialog.fileUrls) // only clears selection if manual not used
let t = filedialog.addSelection("file:/home/user/tempfile.txt");
console.log("add selection success:", t) // a non existent file returns false, so file must exist
filedialog.accept()
}
}
}
}
As variant you can use Qt.labs.platform 1.1 library. It contains FileDialog with a little bit another behavior - file property is not read-only.
And you can do like so:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.4
import Qt.labs.platform 1.1
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
FileDialog {id: filedialog; onAccepted: console.log("File Dialog Accepted: ", file, files);}
Row {
Button {text: "manual"; onClicked: filedialog.open()}
Button {
text: "auto_qml"
onClicked: {
filedialog.file = "file:/home/user/tempfile.txt";
console.log("Current selection:", filedialog.file, filedialog.files)
filedialog.accepted()
}
}
}
}

Call to a python function in the previous Page in the PageStack

I have 2 QML Silica Pages, Main.qml and Icon.qml.
Main.qml has this distribution:
import QtQuick 2.0
import Sailfish.Silica 1.0
import io.thp.pyotherside 1.3
Page {
SilicaFlickable {
id: mainList
Button {
text: "Stack the next page"
onClicked: { // Stack de Icon Page
pageStack.push(Qt.resolvedUrl("Icon.qml"))
}
}
function reload(){ }
Python {
id: py
Component.onCompleted: { mainList.reload() }
}
}
}
And I want to call the function reload() since Icon:
import QtQuick 2.0
import Sailfish.Silica 1.0
import io.thp.pyotherside 1.3
Page {
id: iconEditor
Button {
onClicked: {
pageStack.pop()
pageStack.completeAnimation()
pageStack.currentPage.mainList.reload() // Fail
}
}
}
The Main.qml Page is stacked in the principal QML file like this:
import QtQuick 2.0
import Sailfish.Silica 1.0
import io.thp.pyotherside 1.3
ApplicationWindow {
id: root
Python {
Component.onCompleted: {
pageStack.push(Qt.resolvedUrl("Main.qml"))
}
}
}
How can I call the function on the previous page of the stack?
The "id" have as scope only the .qml where it was defined and cannot (or should be used outside of that scope). If you want to expose objects or variables then you must do it by creating a property in the toplevel of the file.
In this case a solution is to use an alias property:
import QtQuick 2.0
import Sailfish.Silica 1.0
import io.thp.pyotherside 1.3
Page {
property alias mainList: mainList
SilicaFlickable {
id: mainList
// ...

Show message dialog

Is it possible to display a QML dialog when the user hits a button in a QML window?
Example:
When the user clicks in the menu bar on Help -> About the About dialog should be displayed:
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import "components"
ApplicationWindow {
id: window
visible: true
width: 1040
height: 480
aboutDlg: aboutDialog {} // does not work...
menuBar: MenuBar {
Menu {
title: qsTr("Help")
MenuItem {
text: qsTr("About")
onTriggered: aboutDlg.open();
}
}
...
components/AboutDialog.qml
import QtQuick 2.2
import QtQuick.Dialogs 1.1
MessageDialog {
id: aboutDialog
title: "May I have your attention please"
text: "It's so cool that you are using Qt Quick."
onAccepted: {
console.log("And of course you could only agree.")
Qt.quit()
}
}
When I remove the line boutDlg: aboutDialog {} // does not work... the following error is reported when clicking on the About menu item:
qrc:/main.qml:61: ReferenceError: aboutDlg is not defined
How can I achieve this?
You called "aboutDialog" which is an ID in the AboutDialog.
Think of it like you add an object, like adding a Rectangle...which has its own file...and you can "instantiate" it by adding an object like so:
...
ApplicationWindow {
...
AboutDialog {
id: aboutDlg
}
...
}
You can find example HERE
You might also optimize a bit and put the AboutDialog in a Loader.

QML Button press and release color

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.

Refactoring QML and keeping components in scope

I have a larger QML project that I'm trying to refactor so that some related components are in their own file. In my simplified example, what is part of ThingManager.qml was previously simply included in the main.qml file. Prior to refactoring, the scope of ids, a, b, and c were visible to page.qml since they were defined in the main file. As I tried to abstract these into a ThingManager component to reduce clutter in my main.qml, page.qml was no longer able to reference those with the familar scoping error:
page.qml:9: ReferenceError: a is not defined
Given that I am loading pages similar to page.qml and want to execute methods within these components stored in another file, what is the recommended way to refactor something like this example such that page.qml can access methods in these components without them being defined in main.qml? Or is that simply not possible to do?
main.qml:
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQml 2.2
ApplicationWindow {
id: window
ThingManager { }
Loader {
id: page_loader
}
Component.onCompleted: {
page_loader.setSource("page.qml")
}
}
ThingManager.qml:
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
Item {
Column {
Button {
id: a
text: "A"
}
Button {
id: b
text: "B"
}
Button {
id: c
text: "C"
}
}
}
page.qml:
import QtQuick 2.7
import QtQuick.Controls 2.1
Page {
id: page
Component.onCompleted: {
console.log("Execute A's method")
a.toggle()
}
}
You should add an id to ThingManager and define a as an alias property in ThingManager.qml as follows:
main.qml:
...
ThingManager {id: manager }
...
ThingManager.qml:
Item {
property alias a: a // makes 'a' available outside this file
property alias b: b
property alias c: c
...
}
page.qml:
...
manager.a.toggle ()
...

Resources