I have a QQuickControls 2 application that displays an image using a QQuickImageProvider. Sometimes I will simply want to show an unedited image so I just implement my QML like so:
Image {
id: image
fillMode: Image.PreserveAspectFit
source: "image://provider/foo/bar/placeholder.jpg"
}
Other times I will want to show an edited version of the image. How can I tell QQuickImageProvider::requestImage() I want to show an edited version?
QImage ImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
// Somehow determine we need to show an editted version of the image
if (showEdited) {
// maybe pass query parameters to the id?
// for eg 'image://provider/foo/bar/i.jpg?edit=true'
// Then I parse the id string for this query parameter?
cv::Mat src = cv::imread(id.toStdString());
// ... perform some image processing to the image
QImage img = convertMatToQImage(src);
if (size)
*size = QSize(img.width(), img.height());
return img;
}
else {
QImage img(id);
if (size)
*size = QSize(img.width(), img.height());
return img;
}
}
The trigger to show the edited image is by clicking a button:
Button {
id: processBtn
text: qsTr("Process")
onClicked: {
// Somehow call QQuickImageProvider::requestImage() and specify we are editting it?
// Maybe...
// image.source = image.source + "?edit=true"
}
}
I could pass the url of the image, and use the QUrl class to get that edit=true as I show below:
QImage ImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
Q_UNUSED(requestedSize)
QUrl url(id);
bool showEdited = url.query() == "edit=true";
if (showEdited) {
cv::Mat src = cv::imread(url.toLocalFile().toStdString());
///begin process
cv::GaussianBlur(src, src, cv::Size(3,3), 0, 0, cv::BORDER_DEFAULT );
cv::Mat grad_x, grad_y;
cv::Mat abs_grad_x, abs_grad_y, src_gray, grad;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
cv::cvtColor( src, src_gray, CV_BGR2GRAY );
/// Gradient X
cv::Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, cv::BORDER_DEFAULT );
/// Gradient Y
cv::Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, cv::BORDER_DEFAULT );
convertScaleAbs( grad_x, abs_grad_x );
convertScaleAbs( grad_y, abs_grad_y );
addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );
///end process
QImage img = convertMatToQImage(grad);
if (size)
*size = QSize(img.width(), img.height());
return img;
}
else {
QImage img(url.toLocalFile());
if (size)
*size = QSize(img.width(), img.height());
return img;
}
}
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
import QtQuick.Dialogs 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
property string path: ""
onPathChanged: image.source = path == "" ? "": "image://provider/"+ path
ColumnLayout {
anchors.fill: parent
Image {
id: image
Layout.preferredWidth: parent.width
Layout.preferredHeight: parent.height * 0.8
fillMode: Image.PreserveAspectFit
}
Pane {
id: pane
Layout.fillWidth: true
RowLayout {
width: parent.width
Button {
id: selectBtn
text: qsTr("Select")
Layout.alignment: Qt.AlignHCenter
onClicked: fileDialog.open();
}
Button {
id: processBtn
text: qsTr("Process")
Layout.alignment: Qt.AlignHCenter
onClicked: if(path != "") image.source = "image://provider/"+ path + "?edit=true"
}
}
}
}
FileDialog {
id: fileDialog
title: "Please choose a file"
folder: shortcuts.home
nameFilters: [ "Image files (*.jpg *.png)", "All files (*)" ]
onAccepted: path = fileDialog.fileUrl
}
}
Original:
Process:
The complete example can be found on this link.
Use id without extension something like that:
Button {
property bool edit: false
onClicked: {
image.source = "image:://provider/foo/path" + (edit ? placeholder-edit : placeholder )
}
}
But you can implement you QQuickPaintedItem with custom properties without image provider
Related
Why the below code is not working when clicked on cancel button ie., parameterValueText.text is not setting to value 0.
I am assuming both val and parameterValueText.text are binded eachother. If I am wrong, please correct me
Please find below steps
Step 1: Edit a value in Text Input, for ex: 1
Step 2: on Keyboard accepted, parameterValueText.onAccepted is called
Step 3: Click on Save, saveBtn.onClicked is called
Step 4: Click on Cancel, cancelBtn.onClicked is called but the parameterValueText.text is not changed to value 0.
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.VirtualKeyboard 2.1
ApplicationWindow {
id: window
width: 480
height: 272
visible: true
title: qsTr("Keyboard")
property int val: 0
Column {
Item {
id: itemId
height: 20
width: window.width
Rectangle{
width: 100
height: itemId.height
border.color:"black"
TextInput {
id: parameterValueText
text: val //Assuming text and val are binded ??
inputMethodHints: Qt.ImhDigitsOnly
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
onAccepted: console.log("Value = ", parameterValueText.text)
}
}
}
Row {
spacing: 10
Button {
id: saveBtn
text: "Save"
onClicked: console.log("Save = ", parameterValueText.text)
}
Button {
id: cancelBtn
text: "Cancel"
onClicked: val = 0 //Why the value is not changing in parameterValueText.text ?
}
}
}
InputPanel
{
id:inputPanel
y:parent.height
width: window.width
//Background for Virtual Keyboard
Component{
id:keyboardBackground
Rectangle{
color:"#f4f6f3"//ScreenConfiguration.backGroundCanvas
}
}
states: State {
name: "visible"
when: inputPanel.active
PropertyChanges {
target: inputPanel
y: parent.height - inputPanel.height
}
PropertyChanges {
target: inputPanel
}
}
transitions: Transition {
from: ""
to: "visible"
reversible: true
ParallelAnimation {
NumberAnimation {
properties: "y"
duration: 200
easing.type: Easing.InOutQuad
}
}
}
Component.onCompleted: {
keyboard.style.keyboardBackground = keyboardBackground; // the keyboard background
}
}
}
main.cpp
int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
Add below change in .pro file for enabling virtual keyboard
QT += quick virtualkeyboard
The console log ouputs are below
qml: Value = 1, val = 0
qml: Save = 1, val = 0
The binding isn't maintained after the user changes the text using the TextInput (as commenters suggested).
To achieve similar results to what you were attempting you could set val in the TextInput's onAccepted slot, and similarly update both val and parameterValueText.text in the onClicked slots for your buttons as appropriate. For example:
TextInput {
...
onAccepted: {
val = text
}
}
//...
Button {
id: cancelBtn
text: "Cancel"
onClicked: {
val = 0;
parameterValueText.text = val;
}
}
This won't maintain the initial bindings because the values are assigned in imperative javascript, but should achieve resetting values as expected.
As continuation on the answer of #dabbler, you can also recreate the binding in the onAccepted handler, but yeah it's still weird.
parameterValueText.text = Qt.binding(function() { return val; })
As another solution, you could have the val property bind to the text of the input (which then starts with "0"):
readonly property int val: parseInt(parameterValueText.text)
But that only works if the val property is intended to be used as readonly (otherwise you will loose the binding again). In case you want the val property to be set from outside, you could do the following:
onValChanged: parameterValueText.text = val
Note that this is assignment, not binding!
i was trying to make an app with Local Storage for the database and i want to display the data from the database to a listview in different QML file. i know i can make a property alias to the listview so i can access it from another file then append the query result. but when i hit the button to show the data it says that listViewKos was not define but it was already property alias
i did my best to keep the code short, some of the component might have been deleted due to it but appart from the problem i describe above everything works just fine.
#main.qml the JS is just a JS object where the data came from
import QtQuick 2.5
import QtQuick.Controls 2.5
import QtQuick.Dialogs 1.1
import QtQuick.LocalStorage 2.0
import "./Storage.js" as Storage
ApplicationWindow {
id: applicationWindow
width: 640
height: 480
property int kontrakanJumlahKamar
property int kontrakanPrice
property int kosPrice
property string kosGenderType
property alias kosloader: kosloader
property var db
Component.onCompleted: {
db = LocalStorage.openDatabaseSync("ngomahyuk", "1.0", "StorageDatabase", 1000000)
db.transaction(function(tx){
tx.executeSql('CREATE TABLE IF NOT EXISTS kos(namakos TEXT, alamat TEXT, thumbnail TEXT)');
});
// insert data for kos
db.transaction(function(tx){
for (var i = 0; i < Storage.kos.length; i++){
try {
tx.executeSql("INSERT INTO kos (namakos, alamat, thumbnail) VALUES('"+Storage.kos[i].namakos+"','"+Storage.kos[i].alamat+"','"+Storage.kos[i].thumbnail+"'");
} catch (err) {
console.log(err);
}
}
});
}
Button {
id: button
text: qsTr("Search")
MouseArea{
anchors.fill: parent
onClicked:{
if (textFieldHarga.text === ""){
kosPrice = 0
} else {
kosPrice = parseInt(textFieldHarga.text)
}
kosGenderType = comboBoxGender.currentText
kosloader.visible = true
db.transaction(function(tx){
var rs = tx.executeSql("SELECT * FROM kos WHERE gender = '"+kosGenderType+"' AND harga <= "+kosPrice);
if (rs.rows.length === 0){
alertDialogKos.open()
}else {
for (var i = 0; i < rs.rows.length; i++){
listViewKos.model.append({ //this is the one that suppose to be working
imagePath : rs.rows[i].thumbnail,
kosName : rs.rows[i].namakos,
kosAlamat : rs.rows[i].alamat,
})
}
kosloader.source = "Kos.qml"
}
});
}
}
MessageDialog{
// messagedialog code deleted to keep it short
}
background: Rectangle {
// deleted to keep it short
}
contentItem: Text {
id: textItem
text: "Search"
}
}
Loader{
id: kosloader
width: 640
height: 480
opacity: 1
clip: false
visible: false
active: false
anchors.fill: parent
source: ""
}
}
#Kos.qml i use PageBackground.qml as a background
import QtQuick 2.4
import QtQuick.Controls 2.3
PageBackground {
id: kos
width: 640
height: 480
property alias listViewKos: listViewKos
ListView {
id: listViewKos
x: 15
y: 87
width: 640
height: 410
clip: true
model: ListModel{
// need to be in for loop and data from database
}
// delegate listview template
delegate: Item {
height : 195
width : 640
Image {
id: idthumbnail
width: 235
height: 165
source: imagePath
}
Text {
id: idnamakos
x: 252
y: 8
text: kosName
}
Text {
id: idalamat
text: qsTr("Alamat : " + kosAlamat)
}
}
}
}
}
I am trying to make a window where I can draw triangles and delete any of them with a Shape{}. In my example below, I can draw 2 types of triangle:
Up triangle: green and filled
Down triangle: yellow and not filled
Basically, I choose the type of triangle (with a button on the right-bottom corner) then I click anywhere on the window to get a triangle.
Once I click a triangle is created dynamically and it is stored in the property triangleList. Then I call the function shape.update() to update data property of shape. This part works well.
Here the function update I use in the Shape (since data is a list, I have to reassign to a new list.):
function update()
{
data = [];
var d = [];
for (var i = 0; i < canvas.triangleList.length; i++)
{
d.push( canvas.triangleList[i] );
}
data = d;
}
My problem appears when I try to delete a triangle. In my example, I can delete the first, the last or all triangles. When I delete a triangle, first I delete the value in triangleList then I call again shape.update(). It works when I delete all triangles or the last one.
However, when I try to delete the first triangle, data doesn't update its objects even if I give it a new list. In fact, it always deletes the last triangle. Below an example:
data property understands there is one less triangle but it doesn't update the other triangles. The only solution I found is to change a property then come back to the original value. This way, it forces the data to update.
But I have to do that for every property that can be different (colors and positions). Hence, my update() function looks like that:
for (var i = 0; i < canvas.triangleList.length; i++)
{
d.push( canvas.triangleList[i] );
////// Change properties one by one to force the refresh
// Force path redraw. Otherwise only the last path can be deleted
d[i].startX++;d[i].startX--;
// Force line color update
d[i].strokeColor = "red"
d[i].strokeColor = d[i].isUp ? "green" : "yellow";
// Force fill color update
d[i].fillColor = "red";
d[i].fillColor = d[i].isUp ? "green" : "transparent";
data = d;
}
I invite you to comment in/out these lines to see the difference.
I could use this trick to force the update but my real code is really bigger than this example and I use bindings.
So my question is: Is there a way to force the update without having to change each property?
Here the full code if you want to test it:
import QtQuick 2.9;
import QtQuick.Controls 2.2;
import QtQuick.Shapes 1.0;
ApplicationWindow {
visible: true; width: 640; height: 480;
Rectangle {
id: canvas;
anchors.fill: parent;
color: "black";
property var triangleList: [];
property bool triangleUp: true;
MouseArea {
anchors.fill: parent;
onClicked: {
var triangle = componentTriangle.createObject(componentTriangle, {
"isUp" : canvas.triangleUp,
"startX" : mouse.x,
"startY" : mouse.y,
}, canvas);
canvas.triangleList.push(triangle);
shape.update();
}
} // MouseArea
Shape {
id: shape;
anchors.fill: parent;
function update()
{
data = [];
var d = [];
for (var i = 0; i < canvas.triangleList.length; i++)
{
d.push( canvas.triangleList[i] );
///////////// HOW TO AVOID THE PART BELOW? /////////////
////// Change properties one by one to force the refresh
// Force path redraw. Otherwise only the last path can be deleted
d[i].startX++;d[i].startX--;
// Force line color update
d[i].strokeColor = "red"
d[i].strokeColor = d[i].isUp ? "green" : "yellow";
// Force fill color update
d[i].fillColor = "red";
d[i].fillColor = d[i].isUp ? "green" : "transparent";
//////////////////////////////////////////////////////
}
data = d;
// I make sure data has at least one path to ensure the refresh
if (data.length == 0)
data.push(Qt.createQmlObject('import QtQuick 2.9; import QtQuick.Shapes 1.0; ShapePath {startX:0;startY:0;}', canvas,
"force_refresh"));
}
} // Shape
} // Rectangle
//////////// Buttons to handle the triangles
Column {
anchors.bottom: parent.bottom;
anchors.right: parent.right;
Button {
text: canvas.triangleUp? "Draw triangleUp" : "Draw triangleDown";
onClicked: { canvas.triangleUp = !canvas.triangleUp; }
} // Button
Button {
text: "Clear first";
onClicked: {
canvas.triangleList[0].destroy();
canvas.triangleList.splice(0,1);
shape.update();
}
} // Button
Button {
text: "Clear last";
onClicked: {
canvas.triangleList[canvas.triangleList.length -1].destroy();
canvas.triangleList.splice(canvas.triangleList.length -1,1);
shape.update();
}
} // Button
Button {
text: "Clear all";
onClicked: {
for (var i = 0; i < canvas.triangleList.length; i++)
canvas.triangleList[i].destroy();
canvas.triangleList = [];
shape.update();
}
} // Button
}
//////////// Component to draw the triangle
Component {
id: componentTriangle;
ShapePath {
property bool isUp;
property real offsetX: isUp? -20 : 20;
property real offsetY: isUp? -30 : 30;
strokeColor: isUp ? "green" : "yellow";
strokeWidth: 3;
fillColor: isUp ? "green" : "transparent";
PathLine { x: startX - offsetX; y: startY - offsetY }
PathLine { x: startX + offsetX; y: startY - offsetY }
PathLine { x: startX; y: startY }
} // ShapePath
}
}
Thank you very much for your help and feel free to ask me if I was not clear.
Have a nice day!
If you are going to handle many items (Shape) it is advisable to use a Repeater with a model. The repeater is responsible for displaying the items based on the information of the model, and to remove the items you just have to remove items from the model.
main.qml
import QtQuick 2.9;
import QtQuick.Controls 2.2;
import QtQuick.Shapes 1.0;
ApplicationWindow {
visible: true; width: 640; height: 480;
QtObject{
id: internals
property bool triangleUp: true;
}
ListModel{
id: datamodel
}
Rectangle {
id: canvas;
anchors.fill: parent;
color: "black";
Repeater{
model: datamodel
Triangle{
x: model.x
y: model.y
isUp: model.isUp
}
}
MouseArea{
anchors.fill: parent
onClicked: datamodel.append({"x": mouse.x, "y": mouse.y, "isUp": internals.triangleUp})
}
}
Column {
anchors.bottom: parent.bottom;
anchors.right: parent.right;
Button {
text: internals.triangleUp ? "Draw triangleUp" : "Draw triangleDown";
onClicked: internals.triangleUp = !internals.triangleUp;
} // Button
Button {
text: "Clear first";
onClicked: if(datamodel.count > 0) datamodel.remove(0)
} // Button
Button {
text: "Clear last";
onClicked: if(datamodel.count > 0) datamodel.remove(datamodel.count - 1)
} // Button
Button {
text: "Clear all";
onClicked: datamodel.clear()
} // Button
}
}
Triangle.qml
import QtQuick 2.9;
import QtQuick.Shapes 1.0
Shape {
id: shape
property bool isUp: false
QtObject{
id: internals
property real offsetX: isUp? -20 : 20;
property real offsetY: isUp? -30 : 30;
}
ShapePath {
strokeWidth: 3;
strokeColor: isUp ? "green" : "yellow";
fillColor: isUp ? "green" : "transparent";
PathLine { x: -internals.offsetX ; y: -internals.offsetY }
PathLine { x: internals.offsetX; y: -internals.offsetY }
PathLine { x: 0; y: 0 }
}
}
Consider the QML code below, which allows me to insert points onto a blank QML canvas, with mouse-clicks and then clear all the input points and the corresponding pictures on the canvas, using a button placed in the upper-left hand corner
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window{
id: root
width: 640
height: 480
visible: true
Canvas {
id: mycanvas
width: 1000
height: 1000
property var arrpoints : []
onPaint: {
var context = getContext("2d");
// Delete everything drawn before?
context.clearRect(0, 0, mycanvas.width, mycanvas.height);
// Render all the points as small black-circles
context.strokeStyle = Qt.rgba(0, 1, 1, 0)
// Draw all the points
for(var i=0; i < arrpoints.length; i++){
var point = arrpoints[i]
context.ellipse(point["x"], point["y"], 10, 10)
context.fill()
context.stroke()
}
}
// For mousing in points.
MouseArea {
id: mymouse
anchors.fill: parent
onClicked: {
// Record mouse-position into all the input objects
mycanvas.arrpoints.push({"x": mouseX, "y": mouseY})
mycanvas.requestPaint()
console.log( mycanvas.arrpoints )
} // onClicked
}// MouseArea
} // Canvas
Button {
text: "clear input"
onClicked: {
mycanvas.arrpoints.length = 0
mycanvas.requestPaint()
console.log( mycanvas.arrpoints )
}
}
}//Window
This code behaves quite strangely. Suppose I input a few points onto the canvas, and then click the "clear input" button. then as expected all the pictures (ie little circles corresponding to points) vanish from the canvas
and the arrpoints array is set to empty.
But when I start clicking on the canvas again, the cleared pictures are redrawn, alongside the new points being entered!! Why should this be? After printing to the console, I can still see arrpoints=[] so the problem should be with the clearing of the canvas in the onPaint section.
How do I tell QML to erase its canvas memory completely?
If you want to clean the Canvas you must reset the context. In this case, implement a function that does it and force the canvas to update.
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window{
id: root
width: 640
height: 480
visible: true
Canvas {
id: mycanvas
width: 1000
height: 1000
property var arrpoints : []
onPaint: {
var context = getContext("2d");
// Delete everything drawn before?
context.clearRect(0, 0, mycanvas.width, mycanvas.height);
// Render all the points as small black-circles
context.strokeStyle = Qt.rgba(0, 1, 1, 0)
// Draw all the points
for(var i=0; i < arrpoints.length; i++){
var point = arrpoints[i]
context.ellipse(point["x"], point["y"], 10, 10)
context.fill()
context.stroke()
}
}
function clear() {
var ctx = getContext("2d");
ctx.reset();
mycanvas.requestPaint();
}
// For mousing in points.
MouseArea {
id: mymouse
anchors.fill: parent
onClicked: {
// Record mouse-position into all the input objects
mycanvas.arrpoints.push({"x": mouseX, "y": mouseY})
mycanvas.requestPaint()
console.log( mycanvas.arrpoints )
} // onClicked
}// MouseArea
} // Canvas
Button {
text: "clear input"
onClicked: {
mycanvas.arrpoints.length = 0
mycanvas.clear()
console.log( mycanvas.arrpoints )
}
}
}//Window
I finished a Qt Quick UI project, where I am using many QML and audio files. It is an application for children. In the main screen I have 10 sections. One is for letters (Pismena.qml), second for numbers(Cislice.qml) etc (Tvary.qml,Farby.qml). If you choose some section, then you can browse through the images, which are accompanied by sound. One section contains about 30 png and 30 mp3 files. Everything works fine.
But if I want to deploy this application and transform this project into a Qt Quick Application project, I have a problem. For three sections it is OK, but if I want to use four sections, I get errors like:
Error: "Internal data flow error."
Error: "GStreamer encountered a general stream error."
Error: "Failed to connect stream: Too large"
These error messages are displayed immediately when I start the application, not when I am browsing the images.
Also some audio elements are not played.
Here is my main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("applicationDirPath", QGuiApplication::applicationDirPath());
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
Here is my main.qml (it's not complete)
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtGraphicalEffects 1.0
import QtQuick.Window 2.0
import QtMultimedia 5.0
ApplicationWindow {
visible: true
width: 1024
height:300
Rectangle {
width: parent.width
height: parent.height
id: appWindow
property alias pismenaIconAlias: pismenaIcon
Pismena{
id: pismena
visible: false
}
Cislice{
id: cislice
visible: false
}
Farby{
id: farby
visible: false
}
Tvary{
id: tvary
visible: false
}
Image{
id: pismenaIcon
source: "file:" + applicationDirPath + "/obrazky/pismenaIcon.png"
MouseArea{
anchors.fill: parent
hoverEnabled: true
onClicked: {
parent.visible = false
pismena.visible = true
}
}
}
Image{
id: cisliceIcon
source: "file:" + applicationDirPath + "/obrazky/cisliceIcon.png"
MouseArea{
anchors.fill: parent
hoverEnabled: true
onClicked: {
parent.visible = false
cislice.visible = true
}
}
Image{
id: farbyIcon
source: "file:" + applicationDirPath + "/obrazky/farbyIcon.png"
MouseArea{
anchors.fill: parent
hoverEnabled: true
onClicked: {
parent.visible = false
farby.visible = true
}
}
Image{
id: tvaryIcon
source: "file:" + applicationDirPath + "/obrazky/tvaryIcon.png"
MouseArea{
anchors.fill: parent
hoverEnabled: true
onClicked: {
parent.visible = false
tvary.visible = true
}
}
}
}
In the main.qml file, if you choose Pismena(pismenaIcon Image element), you are redirected to that file - Pismena.qml, where you can browse through Images with sounds:
import QtQuick 2.3
import "myJava.js" as MyScript
import QtMultimedia 5.0
import QtQuick.Window 2.0
Item {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Audio {
id: hrajPismeno
}
Image {
id: pis
MouseArea{
anchors.fill: parent
onClicked: {
pis.source = "file:" + applicationDirPath + MyScript.cobr()
hrajPismeno.source = "file:" + applicationDirPath + MyScript.zobr()
hrajPismeno.play()
}
}
}
}
And here is my myJava.js
.pragma library
var pr = 0;
var c = 1;
var z = 1;
var numberOfItems = 33;
var itemFolder = "\/pismena\/";
function cobr(){
c = (c === numberOfItems) ? 0 : c;
c = c + 1;
var s = itemFolder + c + ".png";
return s;
}
function setLetters(){
numberOfItems = 33;
itemFolder = "\/pismena\/";
}
function zobr(){
z = (z === numberOfItems) ? 0 : z;
z = z + 1;
var r = itemFolder + z + ".mp3";
return r;
}
I am using Qt 5.3 On Linux Mint 13.
Why I can not use many Audio files?
In Pismena.qml you have not set the initial width and height for the Item and also for the Image. So in the window there is no place where user can actually click. Also there is no default path for the Image element.
EDIT
In each Audio element, set the autoLoad property to false.