diff --git a/share/qtcreator/templates/wizards/classes/python/file.py b/share/qtcreator/templates/wizards/classes/python/file.py
index 32be237c7a1..adcbc1ed2d0 100644
--- a/share/qtcreator/templates/wizards/classes/python/file.py
+++ b/share/qtcreator/templates/wizards/classes/python/file.py
@@ -1,30 +1,26 @@
-# -*- coding: utf-8 -*-
-
-@if '%{Imports}'
-try:
-@if '%{ImportQtCore}'
- from PySide import QtCore
-@endif
-@if '%{ImportQtWidgets}'
- from PySide import QtWidgets
-@endif
-@if '%{ImportQtQuick}'
- from PySide import QtQuick
-@endif
-except:
-@if '%{ImportQtCore}'
- from PyQt5.QtCore import pyqtSlot as Slot
- from PyQt5 import QtCore
-@endif
-@if '%{ImportQtWidgets}'
- from PyQt5 import QtWidgets
-@endif
-@if '%{ImportQtQuick}'
- from PyQt5 import QtQuick
+# This Python file uses the following encoding: utf-8
+@if '%{Module}' === 'PySide2'
+ @if '%{ImportQtCore}'
+from PySide2 import QtCore
+ @endif
+ @if '%{ImportQtWidgets}'
+from PySide2 import QtWidgets
+ @endif
+ @if '%{ImportQtQuick}'
+from PySide2 import QtQuick
+ @endif
+@else
+ @if '%{ImportQtCore}'
+from PyQt5 import QtCore
+ @endif
+ @if '%{ImportQtWidgets}'
+from PyQt5 import QtWidgets
+ @endif
+ @if '%{ImportQtQuick}'
+from PyQt5 import QtQuick
+ @endif
@endif
-
-@endif
@if '%{Base}'
class %{Class}(%{Base}):
@else
diff --git a/share/qtcreator/templates/wizards/classes/python/wizard.json b/share/qtcreator/templates/wizards/classes/python/wizard.json
index 64c8d8d435a..6d1d72c63bb 100644
--- a/share/qtcreator/templates/wizards/classes/python/wizard.json
+++ b/share/qtcreator/templates/wizards/classes/python/wizard.json
@@ -6,7 +6,7 @@
"trDescription": "Creates new Python class file.",
"trDisplayName": "Python Class",
"trDisplayCategory": "Python",
- "iconText": "py",
+ "icon": "../../files/python/icon.png",
"enabled": "%{JS: [ %{Plugins} ].indexOf('PythonEditor') >= 0}",
"options":
@@ -30,6 +30,15 @@
"type": "LineEdit",
"data": { "validator": "^(?:[^\\d\\W]\\w*|)$" }
},
+ {
+ "name": "Module",
+ "trDisplayName": "Python module:",
+ "type": "ComboBox",
+ "data":
+ {
+ "items": ["PySide2", "PyQt5"]
+ }
+ },
{
"name": "BaseCB",
"trDisplayName": "Base class:",
diff --git a/share/qtcreator/templates/wizards/files/python/file.py b/share/qtcreator/templates/wizards/files/python/file.py
index faa18be5bbf..003f8414973 100644
--- a/share/qtcreator/templates/wizards/files/python/file.py
+++ b/share/qtcreator/templates/wizards/files/python/file.py
@@ -1,2 +1,4 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
+# This Python file uses the following encoding: utf-8
+
+# if__name__ == "__main__":
+# pass
diff --git a/share/qtcreator/templates/wizards/files/python/icon.png b/share/qtcreator/templates/wizards/files/python/icon.png
new file mode 100644
index 00000000000..8ab694fe7af
Binary files /dev/null and b/share/qtcreator/templates/wizards/files/python/icon.png differ
diff --git a/share/qtcreator/templates/wizards/files/python/icon@2x.png b/share/qtcreator/templates/wizards/files/python/icon@2x.png
new file mode 100644
index 00000000000..8d1f2751860
Binary files /dev/null and b/share/qtcreator/templates/wizards/files/python/icon@2x.png differ
diff --git a/share/qtcreator/templates/wizards/files/python/wizard.json b/share/qtcreator/templates/wizards/files/python/wizard.json
index 32b720f3d40..d4a6cfd0126 100644
--- a/share/qtcreator/templates/wizards/files/python/wizard.json
+++ b/share/qtcreator/templates/wizards/files/python/wizard.json
@@ -6,7 +6,7 @@
"trDescription": "Creates an empty Python script file using UTF-8 charset.",
"trDisplayName": "Python File",
"trDisplayCategory": "Python",
- "iconText": "py",
+ "icon": "icon.png",
"enabled": "%{JS: [ %{Plugins} ].indexOf('PythonEditor') >= 0}",
"pages" :
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/icon.png b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/icon.png
new file mode 100644
index 00000000000..483f71196d3
Binary files /dev/null and b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/icon.png differ
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/icon@2x.png b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/icon@2x.png
new file mode 100644
index 00000000000..81beed5e239
Binary files /dev/null and b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/icon@2x.png differ
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json
new file mode 100644
index 00000000000..0f1ce91cf78
--- /dev/null
+++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json
@@ -0,0 +1,51 @@
+{
+ "version": 1,
+ "supportedProjectTypes": [ "PythonProject" ],
+ "id": "U.QtForPythonApplicationEmpty",
+ "category": "F.Application",
+ "trDescription": "Creates a Qt for Python application that only the main code for a QApplication",
+ "trDisplayName": "Qt for Python - Empty",
+ "trDisplayCategory": "Application",
+ "icon": "icon.png",
+ "enabled": "%{JS: [ %{Plugins} ].indexOf('PythonEditor') >= 0}",
+ "featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.6" ],
+
+ "options":
+ [
+ { "key": "MainPyFileName", "value": "main.py" },
+ { "key": "PyProjectFile", "value": "main.pyproject" }
+ ],
+
+ "pages":
+ [
+ {
+ "trDisplayName": "Project Location",
+ "trShortTitle": "Location",
+ "typeId": "Project"
+ },
+ {
+ "trDisplayName": "Project Management",
+ "trShortTitle": "Summary",
+ "typeId": "Summary"
+ }
+ ],
+ "generators":
+ [
+ {
+ "typeId": "File",
+ "data":
+ [
+ {
+ "source": "../main.pyproject",
+ "target": "%{PyProjectFile}",
+ "openAsProject": true
+ },
+ {
+ "source": "../main_empty.py",
+ "target": "%{MainPyFileName}",
+ "openInEditor": true
+ }
+ ]
+ }
+ ]
+}
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/main.pyproject b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/main.pyproject
new file mode 100644
index 00000000000..cc7a74a3468
--- /dev/null
+++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/main.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py"]
+}
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/main_empty.py b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/main_empty.py
new file mode 100644
index 00000000000..6cb021403b9
--- /dev/null
+++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/main_empty.py
@@ -0,0 +1,9 @@
+# This Python file uses the following encoding: utf-8
+import sys
+from PySide2.QtWidgets import QApplication
+
+
+if __name__ == "__main__":
+ app = QApplication([])
+ # ...
+ sys.exit(app.exec_())
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/main_mainwindow.py b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/main_mainwindow.py
new file mode 100644
index 00000000000..fa1f92c7477
--- /dev/null
+++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/main_mainwindow.py
@@ -0,0 +1,15 @@
+# This Python file uses the following encoding: utf-8
+import sys
+from PySide2.QtWidgets import QApplication, QMainWindow
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ QMainWindow.__init__(self)
+
+
+if __name__ == "__main__":
+ app = QApplication([])
+ window = MainWindow()
+ window.show()
+ sys.exit(app.exec_())
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/icon.png b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/icon.png
new file mode 100644
index 00000000000..ba97ffd6620
Binary files /dev/null and b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/icon.png differ
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/icon@2x.png b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/icon@2x.png
new file mode 100644
index 00000000000..4c26be65ba4
Binary files /dev/null and b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/icon@2x.png differ
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json
new file mode 100644
index 00000000000..c98ebb3ed46
--- /dev/null
+++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json
@@ -0,0 +1,51 @@
+{
+ "version": 1,
+ "supportedProjectTypes": [ "Qt4ProjectManager.Qt4Project" ],
+ "id": "U.QtForPythonApplicationWindow",
+ "category": "F.Application",
+ "trDescription": "Creates a Qt for Python application that contains an empty window.",
+ "trDisplayName": "Qt for Python - Window",
+ "trDisplayCategory": "Application",
+ "icon": "icon.png",
+ "enabled": "%{JS: [ %{Plugins} ].indexOf('PythonEditor') >= 0}",
+ "featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.6" ],
+
+ "options":
+ [
+ { "key": "MainPyFileName", "value": "main.py" },
+ { "key": "PyProjectFile", "value": "main.pyproject" }
+ ],
+
+ "pages":
+ [
+ {
+ "trDisplayName": "Project Location",
+ "trShortTitle": "Location",
+ "typeId": "Project"
+ },
+ {
+ "trDisplayName": "Project Management",
+ "trShortTitle": "Summary",
+ "typeId": "Summary"
+ }
+ ],
+ "generators":
+ [
+ {
+ "typeId": "File",
+ "data":
+ [
+ {
+ "source": "../main.pyproject",
+ "target": "%{PyProjectFile}",
+ "openAsProject": true
+ },
+ {
+ "source": "../main_mainwindow.py",
+ "target": "%{MainPyFileName}",
+ "openInEditor": true
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/plugins/pythoneditor/PythonEditor.json.in b/src/plugins/pythoneditor/PythonEditor.json.in
index b4505d55465..89269328b3d 100644
--- a/src/plugins/pythoneditor/PythonEditor.json.in
+++ b/src/plugins/pythoneditor/PythonEditor.json.in
@@ -28,6 +28,7 @@
\" \",
\" \",
\" Qt Creator Python project file\",
+ \" \",
\" \",
\" \",
\"\"
diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp
index 64722ef7496..dfd9c6a50ea 100644
--- a/src/plugins/pythoneditor/pythoneditorplugin.cpp
+++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp
@@ -59,6 +59,10 @@
#include
#include
#include
+#include
+#include
+#include
+#include
using namespace Core;
using namespace ProjectExplorer;
@@ -340,6 +344,35 @@ static QStringList readLines(const Utils::FileName &projectFile)
return lines;
}
+static QStringList readLinesJson(const Utils::FileName &projectFile)
+{
+ const QString projectFileName = projectFile.fileName();
+ QStringList lines = { projectFileName };
+
+ QFile file(projectFile.toString());
+ if (!file.open(QFile::ReadOnly))
+ return lines;
+ const QByteArray content = file.readAll();
+
+ // This assumes te project file is formed with only one field called
+ // 'files' that has a list associated of the files to include in the project.
+ if (!content.isEmpty()) {
+ const QJsonDocument doc = QJsonDocument::fromJson(content);
+ const QJsonObject obj = doc.object();
+ if (obj.contains("files")) {
+ QJsonValue files = obj.value("files");
+ QJsonArray files_array = files.toArray();
+ QSet visited;
+ for (const auto &file : files_array)
+ visited.insert(file.toString());
+
+ lines.append(visited.toList());
+ }
+ }
+
+ return lines;
+}
+
bool PythonProject::saveRawFileList(const QStringList &rawFileList)
{
bool result = saveRawList(rawFileList, projectFilePath().toString());
@@ -418,7 +451,15 @@ bool PythonProject::renameFile(const QString &filePath, const QString &newFilePa
void PythonProject::parseProject()
{
m_rawListEntries.clear();
- m_rawFileList = readLines(projectFilePath());
+ const Utils::FileName filePath = projectFilePath();
+ // The PySide project file is JSON based
+ if (filePath.endsWith(".pyproject"))
+ m_rawFileList = readLinesJson(filePath);
+ // To keep compatibility with PyQt we keep the compatibility with plain
+ // text files as project files.
+ else if (filePath.endsWith(".pyqtc"))
+ m_rawFileList = readLines(filePath);
+
m_files = processEntries(m_rawFileList, &m_rawListEntries);
}
@@ -449,7 +490,7 @@ void PythonProject::refresh(Target *target)
auto newRoot = std::make_unique(this);
for (const QString &f : m_files) {
const QString displayName = baseDir.relativeFilePath(f);
- FileType fileType = f.endsWith(".pyqtc") ? FileType::Project : FileType::Source;
+ FileType fileType = f.endsWith(".pyproject") || f.endsWith(".pyqtc") ? FileType::Project : FileType::Source;
newRoot->addNestedNode(std::make_unique(FileName::fromString(f),
displayName, fileType));
if (fileType == FileType::Source) {
diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg
index 24f73e097e0..86fcbb48d00 100644
--- a/src/tools/icons/qtcreatoricons.svg
+++ b/src/tools/icons/qtcreatoricons.svg
@@ -2645,18 +2645,21 @@
id="path5662-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/manual/debugger/python/README.md b/tests/manual/debugger/python/README.md
index 0ed136ee403..31b9e70a18e 100644
--- a/tests/manual/debugger/python/README.md
+++ b/tests/manual/debugger/python/README.md
@@ -1,4 +1,4 @@
-- qtcreator -load PythonEditor ./python.pyqtc
+- qtcreator -load PythonEditor ./python.pyproject (or ./python.pyqtc)
- Switch active runconfiguration to main.py
-