I am trying to build a simple media player in QML . I can't use QFile Dialog as its a single window application running on EGLFS . I managed so far to build a simple file browser for QML and can play a mp3 from a fixed location. But here is where I am stuck:
How do I set the current selected file from the treeview as source for my audio ?
How can I get the Audio play each file with file ending mp3 from the selected folder?
Thanks for your help
.pro file
QT += qml quick multimedia widgets
CONFIG += c++11
SOURCES += main.cpp
RESOURCES += qml.qrc
QML_IMPORT_PATH =
QML_DESIGNER_IMPORT_PATH =
DEFINES += QT_DEPRECATED_WARNING
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
main.cpp:
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtQml>
#include <QFileSystemModel>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.setOrganizationName("Power-Tune");
app.setOrganizationDomain("power-tune.org");
app.setApplicationName("PowerTune");
QQmlApplicationEngine engine;
//
QFileSystemModel model;
model.setRootPath("/");
engine.rootContext()->setContextProperty("my_model", &model);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
my main.qml :
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
import QtMultimedia 5.8
ApplicationWindow {
visible: true
width: 800
height: 480
minimumWidth: 800
minimumHeight: 480
title: qsTr("PowerTune ")
// visibility: "FullScreen"
color: "black"
Rectangle {
width: parent.width
height: parent.height
property bool playing: false
Audio {
id: playMusic
//source: currently selected file in TreeView
}
Button {
id: previous
text: "previous"
width: 100
anchors.right: playpause.left
// onClicked: select previous item in current folder
}
Button {
id: playpause
text: "play/pause" //playing ? "Stop music" : "Start music"
width: 100
anchors.right: next.left
onClicked: {
if(playing == true) {
playMusic.stop()
playing = false
} else {
playMusic.play()
playing = true
}
}
}
Button {
id: next
text: "next"
width: 100
anchors.right: parent.right
}
TreeView {
id:mp3selector
width: parent.width/2
height: parent.height
TableViewColumn {
title: "Name"
role: "fileName"
width: 300
}
model: my_model
}
}
}
Couple of notes:
property bool playing: false
Properties are better to be defined at top of hierarchy so that they accessible in all children, so prefer to put it directly in ApplicationWindow not in Rectangle element.
And, I think TreeView is not a suitable choice (Its a Quick Controls 1.0 element not available in Quick Controls 2.0 , and for mixing check this post);
You can do the model directly from QML, using a ListView with FolderListModel, you only need an additional of decorations for highlighting and selecting of files with mouse .. that's all, TreeView could be replaced with below code, it works and fancy!
...
import QtQuick.Controls 2.2
import Qt.labs.folderlistmodel 2.1
...
ListView {
id: list
width: parent.width/2
height: parent.height
model: folderModel
onCurrentIndexChanged: {
// This will handle changing playlist with all possible selection methods
playMusic.source = folderModel.get(currentIndex, "fileURL")
}
FolderListModel {
id: folderModel
folder: "file:///MP3/"
showDirs: false
nameFilters: ["*.mp3"]
}
delegate: Component {
Item {
width: parent.width
height: 40
Column {
Text { text: fileName }
}
MouseArea {
anchors.fill: parent
onClicked: {
list.currentIndex = index
}
}
}
}
highlight: Rectangle {
color: 'grey'
}
focus: true
}
For your buttons onClicked just handle currentIndex of the ListView , for example in the next button add:
onClicked: list.currentIndex += 1
you also need to add some code to avoid getting index out of range or -1 ...etc.
Related
I'm developping an app using QT 5.15 LTS (5.15.2). I have the following QML item that I use to handle virtual keyboard interactions :
//InputScreen.qml
import QtQuick 2.3
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.2
import QtQuick.VirtualKeyboard 2.3
Rectangle
{
id: inputScreen
property var target: undefined
width: app.width
height: app.height
color: "#44000000"
z: 200
onVisibleChanged:
{
if (inputScreen.visible == true)
{
fld.text = target.text;
inputPanel.forceActiveFocus();
fld.forceActiveFocus();
fld.clicked(); //Tried to force a click here. Explanation below
}
}
Rectangle
{
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
height: 40
width: 600
z: 201
TextField
{
id: fld
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: 400
height: 40
font.pixelSize: 24
focus: true
}
Button
{
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
width: 200
height: 40
font.pixelSize: 24
text: "Valider"
onClicked:
{
if (target != undefined)
{
target.text = fld.text;
inputScreen.visible = false;
}
}
}
}
InputPanel
{
id: inputPanel
height: 400
width: app.width - 40
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
focus: true
z: 201
}
MouseArea
{
anchors.fill: parent
onClicked:
{
target.text = fld.text;
inputScreen.visible = false;
}
}
}
When my item becomes visible, the textField gets the focus correctly and I can start typing through the InputPanel virtual keyboard. There's however one single problem : the shift key does not work !
In order to make that shift key enable itself, I need to click on the TextField, which beats the purpose of forcing the active focus on it to begin with.
Is there any way to fix that problem ? Or at the very least, is there any kind of workaround I can use to enable that shift key ?
I have already tried to force a click inside my TextField (as seen in the code above), but it didn't work.
For context : here's the content of main.qml as well, in order to give out a working example :
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls 1.4
import QtQuick.VirtualKeyboard 2.3
Window
{
id: app
visible: true
width: 640
height: 480
title: qsTr("Example")
InputScreen
{
id: inputScreen
visible: false
}
Rectangle
{
id: rect
height: parent.height * 0.8
width: parent.width * 0.8
anchors.centerIn: parent
border.color: "#FF0000"
z: 1
TextField
{
id: myField
anchors.centerIn: parent
width: 200
height: 24
MouseArea
{
anchors.fill: parent
onClicked:
{
inputScreen.target = myField;
inputScreen.visible = true;
}
}
}
}
}
I finally managed to find a trick that enabled that shift key without requiring to click on my already focused TextField, and it's actually very simple.
I simply added the following line in the onClicked event of the MouseArea inside the "myField" TextField :
MouseArea
{
anchors.fill: parent
onClicked:
{
parent.focus = true; //This line solved the issue !
//...
}
}
I have no idea why, but somehow this was enough to actually unlock the shift key from my InputPanel virtual keyboard without requiring me to click a second time on the TextField from my InputScreen item. I suppose it has probably something to do with the fact that my MouseArea is hijacking the focus of the "myField" TextField, which triggers some sort of odd behaviour on the InputPanel item despite having another TextField item focused.
In any case, I hope this will help someone.
I use open source qt5.9 for an embedded device.
I wanna to use virtual keyboard in my qml project. I know I should add a static link in .pro file like :
static {
QT += svg
QTPLUGIN += qtvirtualkeyboardplugin
}
and also add
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
to main.cpp file to use the virtual keyboard. but my virtual keyboard does not fire when I click on my text object:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.VirtualKeyboard 2.1
Window {
visible: true
width: 640
height: 480
TextInput {
id: textInput;
text:"ssssss"
height: 120;
width: parent.width - 2;
anchors.bottom: keyboard.top
color: "#000000"; // black
// http://doc.qt.io/qt-5/qinputmethod.html#properties
focus: Qt.inputMethod.visible;
verticalAlignment: TextInput.AlignVCenter;
}
}
It solved.
just put the kind of input for each lineedit . like this :
InputPanel{
id:inputpanel
visible:active
y:active?parent.height - inputpanel.height : parent.height
anchors.left: parent.left
anchors.right: parent.right
}
TextInput{
id:input
inputMethodHints: Qt.ImhDigitsOnly
focus: Qt.inputMethod.visible;
text: "123211"
}
TextInput{
id:input2
anchors.top:input.bottom
inputMethodHints: Qt.ImhLowercaseOnly
focus: Qt.inputMethod.visible;
text: "123211"
}
I am new in Qt & QML, now I set a window and want to set it transparent, user can see my desktop cross my application.
I try to use WA_TranslucentBackground and opacity, however it doesn't work.
Here is my QML code, it's very simple:
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
visible: true
width: Screen.width
height: Screen.height
title: qsTr("Input")
flags: Qt.WA_TranslucentBackground | Qt.FramelessWindowHint
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
}
Window {
visible: true
color: "transparent"
//flags: Qt.Widget | Qt.FramelessWindowHint
}
Uncomment flags if you want transparent window without frame
I am developing an application with Qt and qml and I am building it for OSX, iOS and Android. The application contains a StackView which has only three pages. In the second page I have a five MenuItems and five Dialogs.
While this very simple application has an excellent performance when runs on OSX and Android, it delays up to 3-4 seconds to show the second page on iOS.
I have already tried "Qml Profiler" and I have found out that the delay happens during the creation of the qml file that describes the second page.
I have also tried "Qt Quick Compiler" (Commercial Qt) with no significant difference.
main.qml
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
ApplicationWindow {
id: app
title: "MyApp"
width: 1024
height: 768
visible: true
StackView {
id: stackView
anchors.fill: parent
initialItem: firstPage
}
Component {
id:firstPage
FirstPage {
}
}
}
firstPage.qml
import QtQuick 2.3
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
Item {
id:firstPage
signal collectionClicked(string name)
focus: true
objectName: "firstPage"
Rectangle {
anchors.fill: parent
color: "blue"
}
MouseArea {
anchors.fill: parent
onClicked: {
stackView.push(Qt.resolvedUrl("SecondPage.qml"))
}
}
}
SecondPage.qml
import QtQuick 2.3
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
Item {
id: itemsPage
signal itemClicked()
Rectangle {
id: myRectangle
anchors.fill: parent
color: "red"
Dialog {
id: dialog1
height: 200
width: 300
//onAccepted: ;
}
Dialog {
id: dialog2
height: 200
width: 300
//onAccepted: ;
}
Dialog {
id: dialog3
height: 200
width: 300
//onAccepted: ;
}
Dialog {
id: dialog4
height: 200
width: 300
//onAccepted: ;
}
Dialog {
id: dialog5
height: 200
width: 300
//onAccepted: ;
}
Menu {
id: myMenu
title: "Menu"
MenuItem {
text: "Test"
//onTriggered: ;
}
MenuItem {
text: "Test"
//onTriggered: ;
}
MenuItem {
text: "Test"
//onTriggered: ;
}
MenuItem {
text: "Test"
//onTriggered: ;
}
MenuItem {
text: "Test"
//onTriggered: ;
}
}
}
MouseArea {
anchors.fill: parent
onClicked: stackView.push(Qt.resolvedUrl("ThirdPage.qml"));
}
}
ThirdPage.qml
import QtQuick 2.0
Item {
Rectangle {
anchors.fill: parent
color: "green"
Text {
text: "third page"
}
}
}
I have tried for such a long to find a solution. And I think that it is impossible that there is nobody that has ever tried to make a simple qml application for iOS and faced what I have faced.
Thank you,
Michael
I was reading the Qt documentation for the past couple of hours trying to figure out a way to make a UI created with Qt Quick UI (QML) communicate (interact) with C++ code (functions... etc.).
I've read the 5 or 6 similar questions on here to but I'm kind of confused, I have problems figuring out where to start or what to do first.
I'd appreciate it a lot if someone could take the time and list the steps needed to make this work.
What i've done so far. I tried doing ...>add new Item> C++ class but I failed with an error saying:" failed to add one or more files to project"> It seems like the files (.. .cpp and .h) are created, they were in the folder where the other project files were but not included in the project.
What I wanna do is just something simple like changing the text of the textedit through a C++ function or any other way possible.
//Test.qml (main.qml)
import QtQuick 2.1
import QtQuick.Window 2.0
Rectangle {
id: rootRect
width: Screen.width/2
height: Screen.height/2
color: "gray"
Button{}
Rectangle{
id: textField
width: 120
height: 40
color: "white"
x:274; y: 61
border.color: "blue"
border.width: 4
radius: 2
}
TextEdit {
id: display
x: 274
y: 61
width: 80
height: 20
text: qsTr("Text Edit")
font.pixelSize: 22
color: "black"
anchors.centerIn: textField
}
Rectangle{
id: inputField
width: textField.width
height: textField.height
border.color: "green"
border.width: 3
color: "white"
x: 140; y: 61
}
TextEdit{
id: input
color: "red"
font.pixelSize: 30
anchors.centerIn: inputField
text: "Some Text"
}
}
//Button.cpl
import QtQuick 2.0
import QtQuick.Window 2.0
Item {
property string defaultText: "New Text"
Rectangle{
id: button
width: rootRect.width/6
height: rootRect.height/8
color: "black"
x: 200; y: 200
radius: 10
}
MouseArea{
id: buttonClickArea
width: 0
anchors.rightMargin: 0
anchors.bottomMargin: 0
anchors.fill: button
onClicked: {
display.text = defaultText
}
}
}
Thank you for taking the time to read this and/or any replies.
Using Qt 5.4.0 and Qt Creator 3.3.0, create New Project:
Click New Project
Qt Quick Application
Click Choose...
Name the project and select where to place it
Click Next
Select Qt Quick 2.4 from the drop-down menu
Click Next
Select desired Kit(s)
Click Next
Click Finish
Now You should see open main.qml file with following code:
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
visible: true
MainForm {
anchors.fill: parent
mouseArea.onClicked: {
Qt.quit();
}
}
}
Change it to:
import QtQuick 2.4
import QtQuick.Window 2.2
//### New Code ###
import QtQuick.Controls 1.3
//################
Window {
id: window1
visible: true
//### New Code ###
width: 400
height: 500
TextArea {
id: textArea
readOnly: true
anchors.bottom: textInput.top
anchors.bottomMargin: 6
anchors.right: parent.right
anchors.rightMargin: 8
anchors.left: parent.left
anchors.leftMargin: 7
anchors.top: parent.top
anchors.topMargin: 7
}
TextField {
id: textInput
y: 470
height: 23
anchors.right: sendButton.left
anchors.rightMargin: 6
anchors.bottom: parent.bottom
anchors.bottomMargin: 7
anchors.left: parent.left
anchors.leftMargin: 7
}
Button {
id: sendButton
x: 328
y: 470
width: 64
height: 23
text: qsTr("Send")
anchors.bottom: parent.bottom
anchors.bottomMargin: 7
anchors.right: parent.right
anchors.rightMargin: 8
onClicked: {
CppClass.sendMessage(textInput.text, textArea);
textInput.text = "";
}
}
//################
}
Add C++ Class to Your project:
Right Mouse Click project name in Projects viewer
Click Add New...
Select C++ Class if not already selected
Click Choose...
In Class name filed enter "CppClass"
Set Base class to QObject
Click Next
Click Finish
Open cppclass.h and change it to:
#ifndef CPPCLASS_H
#define CPPCLASS_H
#include <QObject>
//### New Code ###
#include <QQuickItem>
#include <QQuickTextDocument>
#include <QTextDocument>
//################
class CppClass : public QObject
{
Q_OBJECT
public:
explicit CppClass(QObject *parent = 0);
~CppClass();
//### New Code ###
Q_INVOKABLE void sendMessage(const QString &msg, QQuickItem *textArea);
//################
signals:
public slots:
};
#endif // CPPCLASS_H
Open cppclass.cpp and change it to:
#include "cppclass.h"
CppClass::CppClass(QObject *parent) : QObject(parent)
{
}
CppClass::~CppClass()
{
}
//### New Code ###
void CppClass::sendMessage(const QString &msg, QQuickItem *textArea)
{
QTextDocument *textDocument = textArea->property("textDocument").value<QQuickTextDocument*>()->textDocument();
textDocument->setHtml(textDocument->toHtml() + "\n<b>Text sent to Cpp side:</b> <i>" + msg + "</i>");
}
//################
Open main.cpp and change it to:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
//### New Code ###
#include <QQmlContext>
#include "cppclass.h"
//################
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
//### New Code ###
CppClass cppClass;
engine.rootContext()->setContextProperty("CppClass", &cppClass);
//################
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
Run Your application, type some text to Input Field and click send.
In response to Dynamic Remo comment here's another way to have QML and C++ communicate. This approach is based on C++ emitting a signal and QML acting upon it. Following is the code to get it working.
cppclass.h
#ifndef CPPCLASS_H
#define CPPCLASS_H
#include <QObject>
#include <QDateTime>
class CppClass : public QObject
{
Q_OBJECT
public:
explicit CppClass(QObject *parent = 0);
~CppClass();
Q_INVOKABLE void getCurrentTime();
signals:
void timeUpdate(QString currentTime);
public slots:
};
#endif // CPPCLASS_H
cppclass.cpp
#include "cppclass.h"
CppClass::CppClass(QObject *parent) : QObject(parent)
{
}
CppClass::~CppClass()
{
}
void CppClass::getCurrentTime()
{
emit timeUpdate(QDateTime::currentDateTime().toString("ddd dd MMMM yyyy hh:mm:ss.zzz"));
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "cppclass.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
CppClass cppClass;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("CppClass", &cppClass);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml:
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
Window {
id: rootWindow
width: 400
height: 400
visible: true
Connections {
target: CppClass
onTimeUpdate: {
initailizeDllMsg.text = currentTime
}
}
Text {
id: initailizeDllMsg
text: qsTr("{current time placeholder}")
font.pointSize: 14
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
Button {
id: button1
x: 163
y: 357
text: qsTr("Show current time")
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
onClicked: CppClass.getCurrentTime()
}
}