Skip to content

Commit ab42d7b

Browse files
committed
Multithreaded Execution
1 parent c87e6d4 commit ab42d7b

File tree

12 files changed

+158
-59
lines changed

12 files changed

+158
-59
lines changed

About.htm

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<html>
2+
<body>
3+
<b> Express Python </b>
4+
<br />
5+
Written by Bhathiya Perera<br />
6+
<br />
7+
<b>Credits</b>
8+
<ul>
9+
<li>Qt 5.3.2</li>
10+
<li>Python 3.4.2</li>
11+
<li>Frankie Simon's Python Syntax Highlight Code (Modified)</li>
12+
<li>Mateusz Loskot's Embedding Code (Modified)</li>
13+
<li>Train Icon from awicons.com</li>
14+
<li>All Other Icons from Open Icon Library</li>
15+
</ul>
16+
<br />
17+
<b>License</b>
18+
<pre>
19+
Express Python
20+
Copyright (C) 2014 Bhathiya Perera
21+
22+
This program is free software; you can redistribute it and/or modify
23+
it under the terms of the GNU General Public License as published by
24+
the Free Software Foundation; either version 2 of the License, or
25+
(at your option) any later version.
26+
27+
This program is distributed in the hope that it will be useful,
28+
but WITHOUT ANY WARRANTY; without even the implied warranty of
29+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30+
GNU General Public License for more details.
31+
32+
You should have received a copy of the GNU General Public License along
33+
with this program; if not, write to the Free Software Foundation, Inc.,
34+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35+
</pre>
36+
</body>
37+
</html>

CodeEditor/pythonsyntaxhighlighter.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ PythonSyntaxHighlighter::PythonSyntaxHighlighter(QTextDocument* parent)
9393
<< "\\("
9494
<< "\\)"
9595
<< "\\["
96-
<< "]";
96+
<< "\\]";
9797

9898
setStyles();
9999

@@ -141,16 +141,16 @@ void PythonSyntaxHighlighter::initializeRules()
141141
// 'class' followed by an identifier
142142
rules.append(HighlightingRule("\\bclass\\b\\s*(\\w+)", 1, basicStyles.value("defclass")));
143143

144-
// From '#' until a newline
145-
rules.append(HighlightingRule("#[^\\n]*", 0, basicStyles.value("comment")));
146-
147144
// Numeric literals
148145
rules.append(HighlightingRule("\\b[+-]?[0-9]+[lL]?\\b", 0, basicStyles.value("numbers")));
149146
rules.append(HighlightingRule("\\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\\b", 0, basicStyles.value("numbers")));
150147
rules.append(HighlightingRule("\\b[+-]?[0-9]+(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b", 0, basicStyles.value("numbers")));
151148

152149
// tab and space mixed
153150
rules.append(HighlightingRule("[^\\n]*(?:\\t | \\t)[^\\n]*", 0, basicStyles.value("bugs")));
151+
152+
// From '#' until a newline
153+
rules.append(HighlightingRule("#[^\\n]*", 0, basicStyles.value("comment")));
154154
}
155155

156156
void PythonSyntaxHighlighter::highlightBlock(const QString& text)

PyRun.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,5 @@ win32: LIBS += -L$$PWD/../Python34/libs/ -lpython34
4141

4242
INCLUDEPATH += $$PWD/../Python34/include
4343
DEPENDPATH += $$PWD/../Python34/include
44+
45+
OTHER_FILES +=

PyRunResources.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
<file>Icons/Remove.png</file>
1111
<file>Icons/PyRunImg.png</file>
1212
<file>startme.py</file>
13+
<file>About.htm</file>
1314
</qresource>
1415
</RCC>

PythonAccess/emb.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,24 @@
1313
#include <functional>
1414
#include <iostream>
1515
#include <string>
16+
1617
#include "PythonAccess/emb.h"
1718

1819
namespace emb {
1920
MainView* mainView;
21+
PythonWorker* worker;
2022
void setMainView(MainView* _mainView)
2123
{
2224
mainView = _mainView;
2325
}
26+
void setWorker(PythonWorker* _worker)
27+
{
28+
worker = _worker;
29+
}
2430
MainView* getMainView()
2531
{
2632
return mainView;
33+
2734
}
2835
struct StdOut {
2936
PyObject_HEAD
@@ -153,7 +160,7 @@ PyObject* ApiSetInput(PyObject* self, PyObject* args)
153160
if (!PyArg_ParseTuple(args, "s", &data))
154161
return NULL;
155162

156-
mainView->SetInput(QString(data));
163+
emit worker->SetInput(QString(data));
157164

158165
return Py_BuildValue("i", 0);
159166
}
@@ -178,7 +185,7 @@ PyObject* ApiSetOutput(PyObject* self, PyObject* args)
178185
if (!PyArg_ParseTuple(args, "s", &data))
179186
return NULL;
180187

181-
mainView->SetOutput(QString(data));
188+
emit worker->SetOutput(QString(data));
182189

183190
return Py_BuildValue("i", 0);
184191
}
@@ -196,7 +203,7 @@ PyObject* ApiSetCode(PyObject* self, PyObject* args)
196203
if (!PyArg_ParseTuple(args, "s", &data))
197204
return NULL;
198205

199-
mainView->SetCode(QString(data));
206+
emit worker->SetCode(QString(data));
200207

201208
return Py_BuildValue("i", 0);
202209
}
@@ -206,7 +213,7 @@ PyObject* ApiWriteOutput(PyObject* self, PyObject* args)
206213
if (!PyArg_ParseTuple(args, "s", &data))
207214
return NULL;
208215

209-
mainView->WriteOutput(QString(data));
216+
emit worker->WriteOutput(QString(data));
210217

211218
return Py_BuildValue("i", 0);
212219
}

PythonAccess/emb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <cmath>
44
#include "Python.h"
55
#include "UI/mainview.h"
6+
#include "PythonAccess/pythonworker.h"
67
namespace emb {
78

89

@@ -19,6 +20,7 @@ PyObject* ApiSetInput(PyObject* self, PyObject* args);
1920
PyObject* ApiGetInput(PyObject* self, PyObject* args);
2021
void ResetStdOut();
2122
void setMainView(MainView* _mainView);
23+
void setWorker(PythonWorker* _worker);
2224
MainView* getMainView();
2325
void SetStdout(StdOutWriteType write);
2426
PyMODINIT_FUNC PyInitEmbConnect(void);

PythonAccess/pythonworker.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,27 @@
1+
#include "PythonAccess/emb.h"
12
#include "pythonworker.h"
23

3-
PythonWorker::PythonWorker(QObject *parent) :
4-
QObject(parent)
4+
PythonWorker::PythonWorker(QObject* parent)
5+
: QObject(parent)
56
{
67
}
8+
9+
void PythonWorker::RunPython(const QString &startme, const QString& code)
10+
{
11+
emit StartPythonRun();
12+
PyImport_AppendInittab("emb", emb::PyInitEmbConnect);
13+
PyImport_AppendInittab("express_api", emb::PyInitApiConnection);
14+
Py_Initialize();
15+
PyImport_ImportModule("emb");
16+
17+
emb::StdOutWriteType write = [this](std::string s) {
18+
emit this->WriteOutput(QString::fromStdString(s));
19+
};
20+
21+
emb::SetStdout(write);
22+
PyRun_SimpleString(startme.toStdString().c_str());
23+
PyRun_SimpleString(code.toStdString().c_str());
24+
emb::ResetStdOut();
25+
Py_Finalize();
26+
emit EndPythonRun();
27+
}

PythonAccess/pythonworker.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,18 @@ class PythonWorker : public QObject
99
public:
1010
explicit PythonWorker(QObject *parent = 0);
1111

12+
private:
13+
1214
signals:
15+
void WriteOutput(QString result);
16+
void SetInput(QString txt);
17+
void SetOutput(QString txt);
18+
void SetCode(QString txt);
19+
void StartPythonRun();
20+
void EndPythonRun();
1321

1422
public slots:
15-
23+
void RunPython(const QString &startme,const QString &code);
1624
};
1725

1826
#endif // PYTHONWORKER_H

UI/mainview.cpp

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <functional>
22
#include "PythonAccess/emb.h"
3+
#include "PythonAccess/pythonworker.h"
34
#include "UI/mainview.h"
45
#include "ui_mainview.h"
56
#include <QSettings>
@@ -16,15 +17,40 @@ MainView::MainView(QWidget* parent)
1617
: QMainWindow(parent)
1718
, ui(new Ui::MainView)
1819
{
19-
emb::setMainView(this);
2020
ui->setupUi(this);
2121
SetupHighlighter();
22-
LoadStartupScript();
22+
LoadResources();
2323
LoadSettings();
24+
SetupPython();
25+
}
26+
void MainView::SetupPython()
27+
{
28+
emb::setMainView(this);
29+
PythonWorker* worker = new PythonWorker();
30+
emb::setWorker(worker);
31+
worker->moveToThread(&workerThread);
32+
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
33+
connect(this, &MainView::operate, worker, &PythonWorker::RunPython);
34+
connect(worker, &PythonWorker::WriteOutput, this, &MainView::WriteOutput);
35+
connect(worker, &PythonWorker::SetCode, this, &MainView::SetCode);
36+
connect(worker, &PythonWorker::SetInput, this, &MainView::SetInput);
37+
connect(worker, &PythonWorker::SetOutput, this, &MainView::SetOutput);
38+
connect(worker, &PythonWorker::StartPythonRun, this, &MainView::StartPythonRun);
39+
connect(worker, &PythonWorker::EndPythonRun, this, &MainView::EndPythonRun);
40+
workerThread.start();
41+
}
42+
void MainView::StartPythonRun()
43+
{
44+
ui->btnRun->setEnabled(false);
45+
ui->btnRunSnippet->setEnabled(false);
46+
}
47+
void MainView::EndPythonRun()
48+
{
49+
ui->btnRun->setEnabled(true);
50+
ui->btnRunSnippet->setEnabled(true);
2451
}
2552
void MainView::LoadSettings()
2653
{
27-
2854
QSettings settings;
2955
this->restoreState(settings.value(KEY_DOCK_LOCATIONS).toByteArray(), SAVE_STATE_VERSION);
3056
this->restoreGeometry(settings.value(KEY_GEOMETRY).toByteArray());
@@ -39,7 +65,7 @@ void MainView::LoadSettings()
3965
if (pos != -1) {
4066
ui->fntCombo->setCurrentIndex(pos);
4167
}
42-
if (sizeIndex >= 0){
68+
if (sizeIndex >= 0) {
4369
ui->cmbFontSize->setCurrentIndex(sizeIndex);
4470
}
4571

@@ -57,14 +83,19 @@ void MainView::SetupHighlighter()
5783
ui->txtCode->setFocus();
5884
}
5985

60-
void MainView::LoadStartupScript()
86+
void MainView::LoadResources()
6187
{
6288
bool success;
6389
mStartMe = LoadFile(":/data/startme.py", success);
6490

6591
if (!success) {
6692
QMessageBox::warning(this, tr(APP_NAME), tr("Loading startup script failed"));
6793
}
94+
mAbout = LoadFile(":/data/About.htm", success);
95+
if (!success) {
96+
mAbout = tr(APP_NAME " Written by Bhathiya Perera");
97+
}
98+
6899
}
69100
MainView::~MainView()
70101
{
@@ -76,6 +107,8 @@ MainView::~MainView()
76107
settings.setValue(KEY_OUTPUTBOX, this->GetOutput());
77108
settings.setValue(KEY_FONT, ui->fntCombo->currentText());
78109
settings.setValue(KEY_FONTSIZE, ui->cmbFontSize->currentIndex());
110+
workerThread.quit();
111+
workerThread.wait();
79112
delete ui;
80113
}
81114

@@ -173,20 +206,7 @@ void MainView::WriteOutput(QString output)
173206

174207
void MainView::RunPythonCode(const QString& code)
175208
{
176-
PyImport_AppendInittab("emb", emb::PyInitEmbConnect);
177-
PyImport_AppendInittab("expressApi", emb::PyInitApiConnection);
178-
Py_Initialize();
179-
PyImport_ImportModule("emb");
180-
181-
emb::StdOutWriteType write = [](std::string s) {
182-
emb::getMainView()->WriteOutput(QString::fromStdString(s));
183-
};
184-
185-
emb::SetStdout(write);
186-
PyRun_SimpleString(mStartMe.toStdString().c_str());
187-
PyRun_SimpleString(code.toStdString().c_str());
188-
emb::ResetStdOut();
189-
Py_Finalize();
209+
emit operate(mStartMe, code);
190210
}
191211

192212
void MainView::on_btnRun_clicked()
@@ -326,14 +346,7 @@ void MainView::on_btnAddSnippet_clicked()
326346

327347
void MainView::on_btnAbout_clicked()
328348
{
329-
QMessageBox::about(this, tr(APP_NAME), tr("<b>" APP_NAME "</b><br />"
330-
"Written by Bhathiya Perera<br />"
331-
"<br />"
332-
"This Project Depends on<br />"
333-
"Qt5.3, Python<br />"
334-
"Frankie Simon's Python Syntax Highlight Code<br />"
335-
"Mateusz Loskot's Embedding Code<br />"
336-
"<br />"));
349+
QMessageBox::about(this, tr(APP_NAME), mAbout);
337350
}
338351

339352
void MainView::LoadSnippetsToCombo()

UI/mainview.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <QFileDialog>
1212
#include <QMainWindow>
1313
#include <QInputDialog>
14-
14+
#include <QThread>
1515
// internal
1616
#include "CodeEditor/pythonsyntaxhighlighter.h"
1717
#include "CodeEditor/codeeditor.h"
@@ -29,12 +29,8 @@ class MainView : public QMainWindow {
2929
explicit MainView(QWidget* parent = 0);
3030
~MainView();
3131
QString GetInput();
32-
void SetInput(QString txt);
3332
QString GetOutput();
34-
void SetOutput(QString txt);
3533
QString GetCode();
36-
void SetCode(QString txt);
37-
void WriteOutput(QString output);
3834
void SetSnippets(Snippets* snip);
3935
private slots:
4036
void on_btnRun_clicked();
@@ -55,21 +51,32 @@ private slots:
5551
void on_btnRemoveSnippet_clicked();
5652
void on_btnAddSnippet_clicked();
5753
void on_btnAbout_clicked();
54+
void SetInput(QString txt);
55+
void SetOutput(QString txt);
56+
void SetCode(QString txt);
57+
void WriteOutput(QString output);
58+
void StartPythonRun();
59+
void EndPythonRun();
5860

5961
private:
62+
QThread workerThread;
6063
Ui::MainView* ui;
6164
PythonSyntaxHighlighter* mHighlighter;
6265
QString mStartMe;
66+
QString mAbout;
6367
Snippets* mSnippets;
6468
void ChangeFontSize(QFont font, int size);
6569
void SetupHighlighter();
6670
void SaveFile(CodeEditor* codeEditor);
6771
void BrowseAndLoadFile(CodeEditor* codeEditor);
6872
QString LoadFile(const QString& fileName, bool& success);
69-
void LoadStartupScript();
73+
void LoadResources();
7074
void LoadSnippetsToCombo();
7175
void RunPythonCode(const QString& code);
7276
void LoadSettings();
77+
void SetupPython();
78+
signals:
79+
void operate(const QString&, const QString&);
7380
};
7481

7582
#endif // MAINVIEW_H

0 commit comments

Comments
 (0)