I'm new to QT, and I've had difficulty finding resources on the internet, so I thought I'd try my luck here. I am trying to create a QML file that only contains functions (slots?) and import that file into my main application. The functions would specifically be related to handling phone calls (e.g. placeCall, endCall, callDisconnected, etc.). My first thought was to use create a "CallManager.qml" file and use the Component type like so:
import QtQuick 2.12
import QtQml 2.3
Component {
function makeCall(number) { ... }
function endCall() { ... }
// etc.
}
Then, I would do the following in main.qml:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.3
Window {
Button {
x: 0; y: 0
text: "Call"
onClicked: callManager.placeCall("1234567890")
}
CallManager {
id: callManager
}
}
I just want to know if this is a valid way to solve the problem or if there are better practices for achieving the same results.
You can just create a javascript file ".JS" in your resources and then import it like you import any QML file and in this JS file just add your functions and call them from any other QML file
Related
I have 500mb of offline data I would like to use with the OSM QtLocation plugin. I used the sample source code from this blog https://www.qt.io/blog/2017/05/24/qtlocation-using-offline-map-tiles-openstreetmap-plugin. The data in the sample app is embedded in the resource file, I would like to have it in a separate folder on the disk. For a start I would like to get the sample app working with the sample data located in a folder on disk and not as compiled in resource files. When executing the app it still downloads the data from the online server. I have read lots of articles online but none of the solutions are working. I am using Qt 5.15.2, Windows 10 with MSVC compiler.
This is how my code looks like.
import QtQuick 2.7
import QtQuick.Window 2.2
import QtLocation 5.8
Window {
id: win
objectName: "window"
visible: true
width: 512
height: 512
Map {
id: map
anchors.fill: parent
activeMapType: map.supportedMapTypes[1]
zoomLevel: 1
plugin: Plugin {
id: osmPLugin
name: 'osm';
PluginParameter { name: 'osm.mapping.offline.directory'; value: 'file:///c:/offline_tiles/' }
}
}
}
You have to use the path, not the uri:
PluginParameter { name: 'osm.mapping.offline.directory'; value: 'c:/offline_tiles/' }
A QML FileDialog to save a file works fine in debug mode.
The code is:
import QtQuick 2.5
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Dialogs 1.2
import Qt.labs.settings 1.1
import QtQuick.Controls.Styles 1.4
import Qt.labs.platform 1.0
Item {
property string exportSceneName: "exported_scene"
property url exportFolder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation)
signal startExport()
onStartExport: {
runLogic()
}
function runLogic() {
// ...
}
Button {
onClicked: {
fileDialog.open()
}
}
FileDialog {
id: fileDialog
folder: exportFolder
fileMode: FileDialog.SaveFile
title: qsTr("Export Scene As STL")
onAccepted: {
exportFolder = folder
var name = basename(file)
exportSceneName = name
startExport()
}
}
function basename(str) {
return (String(str).slice(String(str).lastIndexOf("/")+1))
}
}
Release mode
Surprisingly, in release mode, the dialog is open-type rather than save-type:
I have tried:
Change the QML imports versions
Clean the release build directory
Modify qtquickcontrols2.conf file
However, none of them worked! I have studied similar posts like this one, but suggestions didn't work. What else can I try? Thanks.
SOLUTION
Fixed by removing this import inside QML file:
import QtQuick.Dialogs 1.2
I'm going to guess that the issue is conflicting FileDialog definitions. Note that both imports QtQuick.Dialogs and Qt.labs.platform provide an object called FileDialog, but they do not use the same API. (There are several other objects like this in QML, and it's really annoying.) So it's probably trying to use one version of the dialog in debug mode, but for some reason choosing the other one in release mode.
The solution is to first of all make sure you remove any imports that you're not actually using. Then if you still need both, then you can label the imports:
import QtQuick.Dialogs 1.2 as QDiag
import Qt.labs.platform 1.0 as QPlat
Then when you create the FileDialog, you'll have to explicitly state which one you want to use.
QDiag.FileDialog {
}
QPlat.FileDialog {
}
Inspired by this Answer QML - Import external JavaScript file I am trying to load a .js file from a external URL.
import QtQuick 2.9
import QtQuick.Window 2.2
import 'http://code.qt.io/cgit/qt/qtdeclarative.git/plain/examples/quick/demos/photoviewer/PhotoViewerCore/script/script.js' as Test
Window {
id: window
visible: true
width: 600
height: 600
Component.onCompleted: console.log('It is:', Test.calculateScale(100, 100, 200) + '!\nMagical!')
}
But with the import 'http://...' statement my application is not even starting / crashes immediately after start (without any error message).
I have the strong feeling that I am missing something to get the external import working, but I have no idea what exactly.
I have just started playing with QML and have a view where I have a bunch of components as follows:
Window {
....
property Component dateTumbler: ControlView {
// Definition follows
}
property Component timeTumbler: ControlView {
// More definition follows
}
// More controls
}
This makes the main QML file very long and cumbersome to edit and maintain. I tried to separate this into different files as follows:
// DateTumblerView.qml
component: DateTumblerView { // Not sure how to inherit here..
// Definition here
}
I'm trying to use it like this:
property component dateTumbler: DateTumblerView {}
However, this never works and the DateTumblerView is never found. I am not sure if I am doing this correctly.
[EDIT]
ControlView is defined as follows:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtMultimedia 5.5
Rectangle {
id: view
property bool darkBackground: false
Text {
id: textSingleton
}
SoundEffect {
id: playCalSound
source: "qrc:/sound/test.wav"
}
}
[END EDIT]
What is the proper way to split QML code into multiple files?
Your DateTumblerView.qml file should look like this:
ControlView {
// More definition follows
}
And you would use it like this:
property Component dateTumbler: DateTumblerView {}
Or:
Component {
id: dateTumbler
DateTumblerView {}
}
Or if you wanted to use it directly:
DateTumblerView {}
It's pretty much the same as when your code was just in one file. Anytime you do <Type> {}, you're inheriting that type and can set or add new properties, functions, and subcomponents. The difference is that it is in a separate file, has a specific name (the name of the file), and you can reuse that code as many times as you want.
For more details, see Defining Custom QML Types for Re-use.
I am using Qt 5.2 and QtQuick 2.2.
In my project I have several modules that are placed in separated directories. My problem is that I can't use dot-separator in typename while defining properties.
For example:
MyRect.qml
import QtQuick 2.2
Rectangle {
id: root
property color rectColor: "white"
color: root.rectColor
}
MyRectInRect.qml
import QtQuick 2.2
import "./" as MyModule
Rectangle {
id: root
property MyModule.MyRect innerRect: MyModule.MyRect { }
// ^ error: Unexpected token `.'; Unexpected token `identifier'
}
I have searched for something that could explain this behavior in the manual, but looks like there is nothing about it there. I guess that dot symbol is not allowed to be used in "type" field of property definition. But is there any way to explicitly define, what component from which module should be used as a type? Cause there may be need of declaring properties with same typenames, but from different modules.
This is a known issue: QTBUG-10822