Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 15 additions & 17 deletions opencodeblocks/graphics/blocks/codeblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@

""" Module for the base OCB Code Block. """


from PyQt5.QtCore import QCoreApplication, QByteArray
from PyQt5.QtCore import QByteArray
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QPushButton, QTextEdit

from ansi2html import Ansi2HTMLConverter

from opencodeblocks.graphics.blocks.block import OCBBlock
from opencodeblocks.graphics.pyeditor import PythonEditor
from opencodeblocks.graphics.worker import Worker

conv = Ansi2HTMLConverter()

Expand Down Expand Up @@ -144,19 +144,17 @@ def init_run_button(self):
def run_code(self):
"""Run the code in the block"""
code = self.source_editor.text()
kernel = self.source_editor.kernel
self.source = code
# Execute the code
kernel.client.execute(code)
done = False
# While the kernel sends messages
while done is False:
# Keep the GUI alive
QCoreApplication.processEvents()
# Save kernel message and display it
output, output_type, done = kernel.update_output()
if done is False:
if output_type == 'text':
self.stdout = output
elif output_type == 'image':
self.image = output
# Create a worker to handle execution
worker = Worker(self.source_editor.kernel, self.source)
worker.signals.stdout.connect(self.handle_stdout)
worker.signals.image.connect(self.handle_image)
self.source_editor.threadpool.start(worker)
Comment on lines +149 to +152
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok for now, we will talk about that point tomorrow anyway


def handle_stdout(self, stdout):
""" Handle the stdout signal """
self.stdout = stdout

def handle_image(self, image):
""" Handle the image signal """
self.image = image
5 changes: 3 additions & 2 deletions opencodeblocks/graphics/pyeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
""" Module for OCB in block python editor. """

from typing import TYPE_CHECKING, List
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QThreadPool, Qt
from PyQt5.QtGui import QFocusEvent, QFont, QFontMetrics, QColor
from PyQt5.Qsci import QsciScintilla, QsciLexerPython
from opencodeblocks.graphics.theme_manager import theme_manager
Expand All @@ -13,7 +13,7 @@
from opencodeblocks.graphics.kernel import Kernel

kernel = Kernel()

threadpool = QThreadPool()

if TYPE_CHECKING:
from opencodeblocks.graphics.view import OCBView
Expand All @@ -33,6 +33,7 @@ def __init__(self, block: OCBBlock):
super().__init__(None)
self.block = block
self.kernel = kernel
self.threadpool = threadpool
self.setText(self.block.source)

self.update_theme()
Expand Down
47 changes: 47 additions & 0 deletions opencodeblocks/graphics/worker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# OpenCodeBlock an open-source tool for modular visual programing in python
# Copyright (C) 2021 Mathïs FEDERICO <https://www.gnu.org/licenses/>

""" Module to create and manage multi-threading workers """

import asyncio
from PyQt5.QtCore import QObject, pyqtSignal, QRunnable


class WorkerSignals(QObject):
""" Defines the signals available from a running worker thread. """
stdout = pyqtSignal(str)
image = pyqtSignal(str)


class Worker(QRunnable):
""" Worker thread """

def __init__(self, kernel, code):
""" Initialize the worker object. """
super(Worker, self).__init__()

self.kernel = kernel
self.code = code
self.signals = WorkerSignals()

async def run_code(self):
""" Run the code in the block """
# Execute the code
self.kernel.client.execute(self.code)
done = False
# While the kernel sends messages
while done is False:
# Save kernel message and send it to the GUI
output, output_type, done = self.kernel.update_output()
if done is False:
if output_type == 'text':
self.signals.stdout.emit(output)
elif output_type == 'image':
self.signals.image.emit(output)

def run(self):
""" Execute the run_code method asynchronously. """
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(self.run_code())
loop.close()