forked from qt-creator/qt-creator
Improve Python generator
The Python generator generates the .qrc resources file, pyproject.toml, main.py and a settings.py files. This way, pyside6-project can run the code without doing any change in the QML code. Change-Id: Iddcc0c7f7a48c581f656f6d156b17460d4106691 Reviewed-by: Knud Dollereder <knud.dollereder@qt.io>
This commit is contained in:
committed by
Jaime Resano
parent
1278473e69
commit
4146d1bd01
@@ -11,5 +11,8 @@
|
||||
<file alias="import_qml_components_h">templates/import_qml_components_h.tpl</file>
|
||||
<file alias="qtquickcontrols_conf">templates/qtquickcontrols2_conf.tpl</file>
|
||||
<file alias="cmake_shared">templates/cmakelists_txt_shared.tpl</file>
|
||||
<file alias="python_generator_main">templates/python_generator_main.tpl</file>
|
||||
<file alias="python_generator_settings">templates/python_generator_settings.tpl</file>
|
||||
<file alias="python_pyproject_toml">templates/python_pyproject_toml.tpl</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -30,6 +30,7 @@ void Exporter::updateProject(QmlProject *project)
|
||||
void Exporter::updateProjectItem(QmlProjectItem *item, bool updateEnabled)
|
||||
{
|
||||
connect(item, &QmlProjectItem::filesChanged, m_cmakeGen, &CMakeGenerator::update);
|
||||
connect(item, &QmlProjectItem::filesChanged, m_pythonGen, &PythonGenerator::update);
|
||||
connect(item, &QmlProjectItem::fileModified, m_cmakeGen, &CMakeGenerator::updateModifiedFile);
|
||||
|
||||
if (updateEnabled) {
|
||||
|
@@ -3,41 +3,14 @@
|
||||
|
||||
#include "pythongenerator.h"
|
||||
#include "cmakewriter.h"
|
||||
#include "resourcegenerator.h"
|
||||
|
||||
#include "projectexplorer/projectmanager.h"
|
||||
#include "qmlprojectmanager/qmlproject.h"
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
namespace QmlProjectExporter {
|
||||
|
||||
const char *PYTHON_MAIN_FILE_TEMPLATE = R"(
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6.QtGui import QGuiApplication
|
||||
from PySide6.QtQml import QQmlApplicationEngine
|
||||
|
||||
from autogen.settings import url, import_paths
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QGuiApplication(sys.argv)
|
||||
engine = QQmlApplicationEngine()
|
||||
|
||||
app_dir = Path(__file__).parent.parent
|
||||
|
||||
engine.addImportPath(os.fspath(app_dir))
|
||||
for path in import_paths:
|
||||
engine.addImportPath(os.fspath(app_dir / path))
|
||||
|
||||
engine.load(os.fspath(app_dir/url))
|
||||
if not engine.rootObjects():
|
||||
sys.exit(-1)
|
||||
sys.exit(app.exec())
|
||||
)";
|
||||
namespace QmlProjectManager::QmlProjectExporter {
|
||||
|
||||
void PythonGenerator::createMenuAction(QObject *parent)
|
||||
{
|
||||
@@ -66,8 +39,7 @@ PythonGenerator::PythonGenerator(QmlBuildSystem *bs)
|
||||
|
||||
void PythonGenerator::updateMenuAction()
|
||||
{
|
||||
FileGenerator::updateMenuAction(
|
||||
"QmlProject.EnablePythonGenerator",
|
||||
FileGenerator::updateMenuAction("QmlProject.EnablePythonGenerator",
|
||||
[this]() { return buildSystem()->enablePythonGeneration(); });
|
||||
}
|
||||
|
||||
@@ -77,38 +49,47 @@ void PythonGenerator::updateProject(QmlProject *project)
|
||||
return;
|
||||
|
||||
Utils::FilePath projectPath = project->rootProjectDirectory();
|
||||
Utils::FilePath pythonPath = projectPath.pathAppended("Python");
|
||||
if (!pythonPath.exists())
|
||||
pythonPath.createDir();
|
||||
Utils::FilePath pythonFolderPath = projectPath.pathAppended("Python");
|
||||
if (!pythonFolderPath.exists())
|
||||
pythonFolderPath.createDir();
|
||||
|
||||
Utils::FilePath mainFile = pythonPath.pathAppended("main.py");
|
||||
if (!mainFile.exists()) {
|
||||
const QString mainContent = QString::fromUtf8(PYTHON_MAIN_FILE_TEMPLATE);
|
||||
CMakeWriter::writeFile(mainFile, mainContent);
|
||||
Utils::FilePath mainFilePath = pythonFolderPath.pathAppended("main.py");
|
||||
if (!mainFilePath.exists()) {
|
||||
const QString mainFileTemplate = CMakeWriter::readTemplate(
|
||||
":/templates/python_generator_main");
|
||||
CMakeWriter::writeFile(mainFilePath, mainFileTemplate);
|
||||
}
|
||||
|
||||
Utils::FilePath autogenPath = pythonPath.pathAppended("autogen");
|
||||
if (!autogenPath.exists())
|
||||
autogenPath.createDir();
|
||||
Utils::FilePath pyprojectFilePath = pythonFolderPath.pathAppended("pyproject.toml");
|
||||
if (!pyprojectFilePath.exists()) {
|
||||
const QString pyprojectFileTemplate = CMakeWriter::readTemplate(
|
||||
":/templates/python_pyproject_toml");
|
||||
const QString pyprojectFileContent = pyprojectFileTemplate.arg(project->displayName());
|
||||
CMakeWriter::writeFile(pyprojectFilePath, pyprojectFileContent);
|
||||
}
|
||||
|
||||
Utils::FilePath settingsPath = autogenPath.pathAppended("settings.py");
|
||||
CMakeWriter::writeFile(settingsPath, settingsFileContent());
|
||||
Utils::FilePath autogenFolderPath = pythonFolderPath.pathAppended("autogen");
|
||||
if (!autogenFolderPath.exists())
|
||||
autogenFolderPath.createDir();
|
||||
|
||||
Utils::FilePath settingsFilePath = autogenFolderPath.pathAppended("settings.py");
|
||||
const QString settingsFileTemplate = CMakeWriter::readTemplate(
|
||||
":/templates/python_generator_settings");
|
||||
const QString settingsFileContent = settingsFileTemplate.arg(buildSystem()->mainFile());
|
||||
CMakeWriter::writeFile(settingsFilePath, settingsFileContent);
|
||||
|
||||
// Python code uses the Qt resources collection file (.qrc)
|
||||
ResourceGenerator::createQrc(project);
|
||||
}
|
||||
|
||||
QString PythonGenerator::settingsFileContent() const
|
||||
{
|
||||
QTC_ASSERT(buildSystem(), return {});
|
||||
/*!
|
||||
Regenerates the .qrc resources file
|
||||
*/
|
||||
void PythonGenerator::update(const QSet<QString> &added, const QSet<QString> &removed) {
|
||||
Q_UNUSED(added);
|
||||
Q_UNUSED(removed);
|
||||
ResourceGenerator::createQrc(qmlProject());
|
||||
// Generated Python code does not need to be updated
|
||||
};
|
||||
|
||||
QString content("\n");
|
||||
content.append("url = \"" + buildSystem()->mainFile() + "\"\n");
|
||||
|
||||
content.append("import_paths = [\n");
|
||||
for (const QString &path : buildSystem()->importPaths())
|
||||
content.append("\t\"" + path + "\",\n");
|
||||
content.append("]\n");
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
} // namespace QmlProjectExporter.
|
||||
} // namespace QmlProjectManager.
|
||||
} // namespace QmlProjectExporter::QmlProjectManager.
|
||||
|
@@ -21,11 +21,10 @@ public:
|
||||
static void createMenuAction(QObject *parent);
|
||||
|
||||
PythonGenerator(QmlBuildSystem *bs);
|
||||
|
||||
void update(const QSet<QString> &added, const QSet<QString> &removed);
|
||||
void updateMenuAction() override;
|
||||
void updateProject(QmlProject *project) override;
|
||||
|
||||
private:
|
||||
QString settingsFileContent() const;
|
||||
};
|
||||
|
||||
} // namespace QmlProjectExporter.
|
||||
|
@@ -0,0 +1,26 @@
|
||||
import sys
|
||||
|
||||
from PySide6.QtGui import QGuiApplication
|
||||
from PySide6.QtQml import QQmlApplicationEngine
|
||||
|
||||
from autogen.settings import setup_qt_environment
|
||||
|
||||
# Import here the Python files that define QML elements
|
||||
|
||||
|
||||
def main():
|
||||
app = QGuiApplication(sys.argv)
|
||||
engine = QQmlApplicationEngine()
|
||||
|
||||
setup_qt_environment(engine)
|
||||
|
||||
if not engine.rootObjects():
|
||||
sys.exit(-1)
|
||||
|
||||
ex = app.exec()
|
||||
del engine
|
||||
return ex
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
@@ -0,0 +1,36 @@
|
||||
# This file is automatically generated by Qt Design Studio.
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6.QtQml import QQmlApplicationEngine
|
||||
|
||||
project_root = Path(__file__).parent.parent.parent
|
||||
|
||||
|
||||
def setup_qt_environment(qml_engine: QQmlApplicationEngine):
|
||||
"""
|
||||
Load the QML application. Import the compiled resources when the application is deployed.
|
||||
"""
|
||||
qml_app_url = "%1"
|
||||
|
||||
if "__compiled__" in globals():
|
||||
# Application has been deployed using pyside6-deploy
|
||||
try:
|
||||
import autogen.resources # noqa: F401
|
||||
except ImportError:
|
||||
resource_file = Path(__file__).parent / "resources.py"
|
||||
print(
|
||||
f"Error: No compiled resources found in {resource_file.absolute()}\n"
|
||||
f"Please compile the resources using pyside6-rcc or pyside6-project build",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
qml_engine.addImportPath(":/")
|
||||
qml_engine.load(f":/{qml_app_url}")
|
||||
return
|
||||
|
||||
qml_engine.addImportPath(str(project_root.absolute()))
|
||||
os.environ["QT_QUICK_CONTROLS_CONF"] = str(project_root / "qtquickcontrols2.conf")
|
||||
qml_engine.load(str(project_root / qml_app_url))
|
@@ -0,0 +1,5 @@
|
||||
[project]
|
||||
name = "%1"
|
||||
|
||||
[tool.pyside6-project]
|
||||
files = ["main.py", "autogen/settings.py"]
|
Reference in New Issue
Block a user