I need advice on how to specify the paths to my QML and resources (icon) in my simple QtQuick QML Python application on KDE. The only related question I found here was: Deploy a Qt project on linux
My question is different. My only target for deploying my application is KDE; therefore, I do not need to bundle Qt libraries and my application has no other dependencies. I only need to deploy my python and QML files and an application icon (png).
One other wrinkle is that, in the future, I want to be able to provide certain updates via QML files only. I plan to push out, when needed, a single new QML file without having to deploy a new version of the application.
This leads me to believe that I should not use Qt resource system. However, lacking any experience with that system or with deploying applications in general, I seek advice.
I do not want to hard code the path to my icon and main QML file in my main.py file upon deploying. Furthermore, the following code does not give me the location of any of my application's files:
QCoreApplication.applicationDirPath()
It returns /usr/bin
(the location of python) which is not a location suitable for my QML file or application icon.
How can I locate my QML and resource files within the executing __main__
method?
Here is my main.py:
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtGui import QIcon
if __name__ == '__main__':
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load(QUrl.fromLocalFile('view.qml'))
app.setWindowIcon(QIcon('appicon.png'))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
Here is my view.qml
import QtQuick.Window 2.2
import QtQuick 2.2
import QtQuick.Controls 2.14
Window {
id: root
visible: true
width: 640
height: 480
title: qsTr("Hello World")
}
This code works when I execute python main.py
from the local directory. However, if I deploy my python, qml and icon files to, say, /usr/local/bin
I have to hard-code that path into the python file as follows.
engine.load(QUrl.fromLocalFile('/usr/local/bin/view.qml'))
app.setWindowIcon(QIcon('/usr/local/bin/appicon.png'))
I do not want to do this. I am looking for other alternatives that do not involve hard-coding the path.
This question is not about distribution-specific packaging. Assume I will use something like the "generic" method discussed here -- such as a shell script (and assume the installing user will have sudo rights).
The idea in this case is to create absolute paths using relative paths with respect to a main element. For example in this case you could use the main.py directory path (which can be obtained by the solutions provided to this answer: How do I get the path and name of the file that is currently executing?) to obtain the other paths.
import os
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
if __name__ == "__main__":
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load(QUrl.fromLocalFile(os.path.join(CURRENT_DIR, "view.qml")))
app.setWindowIcon(QIcon(os.path.join(CURRENT_DIR, "appicon.png")))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
├── appicon.png
├── main.py
└── view.qml