Add Qt for Python templates and better support
QtCreator: * Add new icons * Add support for `.pyproject` files, * Set `.pyproject` as default, but keep compatibility with `.pyqtc` * `.pyproject` is a JSON file, while `.pyqtc` is a plain-text. Python class: * Add option to ask if use PySide2 or PyQt5 * Remove the old import try-except structure * Remove iconText and add icon option * Remove shebang * Add utf-8 support Python file: * Remove code * Remove iconText and add icon option * Remove shebang * Add utf-8 support Qt for Python - Empty * Add file with basic statements to execute a QApplication Qt for Python - Window * Add file with basic statements to execute a QApplication, which contains a QMainWindow Task-number: QTCREATORBUG-21824 Change-Id: I4adb3ab6b179f084c7b674a6d4f643445fe24929 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Alessandro Portale <alessandro.portale@qt.io> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
@@ -1,19 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
@if '%{Imports}'
|
||||
try:
|
||||
# This Python file uses the following encoding: utf-8
|
||||
@if '%{Module}' === 'PySide2'
|
||||
@if '%{ImportQtCore}'
|
||||
from PySide import QtCore
|
||||
from PySide2 import QtCore
|
||||
@endif
|
||||
@if '%{ImportQtWidgets}'
|
||||
from PySide import QtWidgets
|
||||
from PySide2 import QtWidgets
|
||||
@endif
|
||||
@if '%{ImportQtQuick}'
|
||||
from PySide import QtQuick
|
||||
from PySide2 import QtQuick
|
||||
@endif
|
||||
except:
|
||||
@else
|
||||
@if '%{ImportQtCore}'
|
||||
from PyQt5.QtCore import pyqtSlot as Slot
|
||||
from PyQt5 import QtCore
|
||||
@endif
|
||||
@if '%{ImportQtWidgets}'
|
||||
@@ -22,9 +19,8 @@ except:
|
||||
@if '%{ImportQtQuick}'
|
||||
from PyQt5 import QtQuick
|
||||
@endif
|
||||
|
||||
|
||||
@endif
|
||||
|
||||
@if '%{Base}'
|
||||
class %{Class}(%{Base}):
|
||||
@else
|
||||
|
@@ -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:",
|
||||
|
@@ -1,2 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# This Python file uses the following encoding: utf-8
|
||||
|
||||
# if__name__ == "__main__":
|
||||
# pass
|
||||
|
BIN
share/qtcreator/templates/wizards/files/python/icon.png
Normal file
After Width: | Height: | Size: 606 B |
BIN
share/qtcreator/templates/wizards/files/python/icon@2x.png
Normal file
After Width: | Height: | Size: 989 B |
@@ -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" :
|
||||
|
After Width: | Height: | Size: 728 B |
After Width: | Height: | Size: 1.3 KiB |
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"files": ["main.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_())
|
@@ -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_())
|
After Width: | Height: | Size: 855 B |
After Width: | Height: | Size: 1.5 KiB |
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -28,6 +28,7 @@
|
||||
\" <mime-type type=\'text/x-python-project\'>\",
|
||||
\" <sub-class-of type=\'text/x-python\'/>\",
|
||||
\" <comment>Qt Creator Python project file</comment>\",
|
||||
\" <glob pattern=\'*.pyproject\'/>\",
|
||||
\" <glob pattern=\'*.pyqtc\'/>\",
|
||||
\" </mime-type>\",
|
||||
\"</mime-info>\"
|
||||
|
@@ -59,6 +59,10 @@
|
||||
#include <QRegularExpression>
|
||||
#include <QRegularExpressionMatch>
|
||||
#include <QTextCursor>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonArray>
|
||||
|
||||
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<QString> 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<PythonProjectNode>(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<PythonFileNode>(FileName::fromString(f),
|
||||
displayName, fileType));
|
||||
if (fileType == FileType::Source) {
|
||||
|
@@ -2645,18 +2645,21 @@
|
||||
id="path5662-0"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<g
|
||||
id="tempateIconGuiWizarfTitleBar">
|
||||
<path
|
||||
sodipodi:nodetypes="sssccss"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect7867-7-1-4-6-13-8-3"
|
||||
style="fill:#3a4055"
|
||||
d="m 587.94531,306.94336 h 33.10938 c 0.81824,0 1.3335,0.62105 1.44531,1.43164 V 311 h -36 v -2.625 c 0,-0.81826 0.62707,-1.43164 1.44531,-1.43164 z"
|
||||
style="fill:#3a4055" />
|
||||
<path
|
||||
id="rect5668-6"
|
||||
style="fill:#dfe0e3"
|
||||
d="m 619.5,308 h 2 v 2 h -2 z m -32,0 h 10 v 2 h -10 z"
|
||||
id="rect7867-7-1-4-6-13-8-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
sodipodi:nodetypes="sssccss" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 619.5,308 h 2 v 2 h -2 z m -32,0 h 10 v 2 h -10 z"
|
||||
style="fill:#dfe0e3"
|
||||
id="rect5668-6" />
|
||||
</g>
|
||||
</g>
|
||||
<use
|
||||
x="0"
|
||||
@@ -2666,6 +2669,152 @@
|
||||
transform="translate(60,0)"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
<g
|
||||
id="pythonSnake"
|
||||
transform="matrix(1.03639,0,0,1.03639,42.698825,-127.31617)">
|
||||
<path
|
||||
style="stroke-width:0.62522024"
|
||||
d="m 493.40157,381.58661 c -1.64186,0.28728 -1.95327,1.12936 -1.98311,2.23791 v 1.47075 h 3.8497 l 0.0197,0.96489 h -3.88913 -1.45286 c -1.12761,0 -2.07681,0.6104 -2.5352,1.9502 -0.45839,1.3398 -0.43103,2.68855 0,4.05417 0.43103,1.36562 0.93069,1.7217 2.05828,1.71476 l 0.98462,-5e-5 v -1.46166 c 0,-1.43884 1.23626,-2.39787 2.71574,-2.39787 h 4.24283 c 1.07877,0 1.73984,-0.59015 1.73527,-1.66316 l -0.0197,-4.63208 c -0.004,-1.04142 -0.79695,-2.06408 -1.84987,-2.2379 -0.66651,-0.10988 -1.35625,-0.15393 -2.01952,-0.15085 -0.66326,0.003 -1.2994,0.0532 -1.85674,0.15089 z m -0.53661,1.53569 c 0.40077,0 0.72642,0.32748 0.72642,0.73256 0,0.40364 -0.32565,0.72932 -0.72642,0.72932 -0.40221,0 -0.72644,-0.3258 -0.72644,-0.72944 0,-0.40508 0.32423,-0.73244 0.72644,-0.73244 z"
|
||||
id="path1631"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ssccccszzscssssscccssssss" />
|
||||
</g>
|
||||
<g
|
||||
id="pythonLogo">
|
||||
<use
|
||||
style="fill:#3a4055;fill-opacity:1"
|
||||
height="100%"
|
||||
width="100%"
|
||||
transform="translate(16)"
|
||||
id="use1658"
|
||||
xlink:href="#pythonSnake"
|
||||
y="0"
|
||||
x="0" />
|
||||
<use
|
||||
style="fill:#848895;fill-opacity:1"
|
||||
height="100%"
|
||||
width="100%"
|
||||
transform="rotate(180,564.00512,277.49996)"
|
||||
id="use1660"
|
||||
xlink:href="#pythonSnake"
|
||||
y="0"
|
||||
x="0" />
|
||||
</g>
|
||||
<g
|
||||
id="share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/icon">
|
||||
<use
|
||||
style="display:inline"
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#transparentBackgroundRect_60_60"
|
||||
id="use6218"
|
||||
width="100%"
|
||||
height="100%"
|
||||
transform="translate(540,60)" />
|
||||
<use
|
||||
style="display:inline"
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#wizardicons_laptop"
|
||||
id="use6220"
|
||||
width="100%"
|
||||
height="100%"
|
||||
transform="translate(55,-78)" />
|
||||
<use
|
||||
transform="translate(-11.997289,-36)"
|
||||
height="100%"
|
||||
width="100%"
|
||||
id="use6176"
|
||||
xlink:href="#pythonLogo"
|
||||
y="0"
|
||||
x="0"
|
||||
style="display:inline" />
|
||||
<path
|
||||
style="display:inline;fill:#3a4055;stroke-width:1"
|
||||
d="m 571,238 -6e-4,10.32943 2.47755,-1.72702 1.42512,3.25135 2.17205,-0.94811 -1.42511,-3.25136 2.95258,-0.64325 z"
|
||||
id="path6222"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<use
|
||||
transform="translate(-38.5,-80)"
|
||||
style="display:inline"
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#tempateIconGuiWizarfTitleBar"
|
||||
id="use6247"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(115,-78)"
|
||||
id="share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/icon">
|
||||
<use
|
||||
transform="translate(485,138)"
|
||||
height="100%"
|
||||
width="100%"
|
||||
id="use6264"
|
||||
xlink:href="#transparentBackgroundRect_60_60"
|
||||
y="0"
|
||||
x="0"
|
||||
style="display:inline" />
|
||||
<g
|
||||
transform="translate(0,-1)"
|
||||
id="g6272">
|
||||
<path
|
||||
sodipodi:nodetypes="sssccss"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6266"
|
||||
d="m 494.5,304.5 h 33 c 1.58695,0 3,1.41305 3,3 v 25 h -39 v -25 c 0,-1.58696 1.41305,-3 3,-3 z"
|
||||
style="fill:#fbfbfb;stroke:#6b7080;stroke-width:3" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6268"
|
||||
d="m 535,333 h -48 c 0,2 1,3 3,4 h 42 c 2,-1 3,-2 3,-4 z"
|
||||
style="fill:#848895" />
|
||||
<path
|
||||
sodipodi:nodetypes="csscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6270"
|
||||
d="m 517,333 c 0,0.77906 -0.69638,1 -1.61124,1 H 506.5 c -0.91487,0 -1.69151,-0.22094 -1.69151,-1 z"
|
||||
style="fill:#53586b" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 502,325 h 6 v 1 h -6 z m -5.75012,-7 h 1.5 l 4,4 -4,4 h -1.5 l 4,-4 z"
|
||||
style="fill:#3a4055;stroke-width:1"
|
||||
id="path6274" />
|
||||
<use
|
||||
style="display:inline"
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#pythonLogo"
|
||||
id="use6278"
|
||||
width="100%"
|
||||
height="100%"
|
||||
transform="translate(-54.999998,40)" />
|
||||
</g>
|
||||
<g
|
||||
id="share/qtcreator/templates/wizards/files/python/icon">
|
||||
<use
|
||||
height="100%"
|
||||
width="100%"
|
||||
transform="translate(480,60)"
|
||||
id="use8679"
|
||||
xlink:href="#src/libs/utils/images/wizardicon-file"
|
||||
y="0"
|
||||
x="0" />
|
||||
<use
|
||||
height="100%"
|
||||
width="100%"
|
||||
id="use8681"
|
||||
xlink:href="#use6278"
|
||||
y="0"
|
||||
x="0"
|
||||
style="display:inline"
|
||||
transform="translate(169,-74)" />
|
||||
</g>
|
||||
<g
|
||||
id="src/plugins/coreplugin/images/settingscategory_core"
|
||||
transform="translate(-364,-84)">
|
||||
|
Before Width: | Height: | Size: 363 KiB After Width: | Height: | Size: 368 KiB |
@@ -1,4 +1,4 @@
|
||||
|
||||
- qtcreator -load PythonEditor ./python.pyqtc
|
||||
- qtcreator -load PythonEditor ./python.pyproject (or ./python.pyqtc)
|
||||
- Switch active runconfiguration to main.py
|
||||
- <F10>
|
||||
|