The source files are all in examples directory.
Example implementation for callbacks with a QueuedService (Code)
Example implementation for a QueuedService (Code)
Demonstrates the need of using the signal/slot mechanism instead of normal function calls. (Code)
Examples used for the tutorial. See Warehouse example.
Callback Object Example
callback_events/callback_objects.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
CALLBACK OBJECT EXAMPLE
-----------------------
Example implementation for callbacks to the main thread
using a CallbackObject and a normal Service
.. created on 17.09.2013
.. codeauthor:: Philipp Brimmers
<P.Brimmers@yahoo.de>
'''
from __future__ import print_function, unicode_literals, division
# Built-In
import time
# External
# Internal
import PyroMP.log_server as log
from PyroMP import (callback,
CallbackObject,
CallbackServer,
Event,
NameServer,
Service)
class TestService(Service):
def __init__(self, multiplex=False, async=True):
super(TestService, self).__init__(multiplex, async)
self.event = Event()
def callback(self, callback):
# call callback function directly
callback.call("Callback test")
def send_message(self, msg):
# trigger event with argument
self.event.trigger(msg)
def trigger_event(self):
self.event.trigger()
class LogObject(CallbackObject):
"""Object which receives the callbacks
"""
def __init__(self, name):
super(LogObject, self).__init__()
self.name = name
self.logger = log.create_logger(name)
@callback
def log(self, msg=None):
self.logger.info("log(msg={!r})".format(msg))
if msg is not None:
self.logger.info(msg)
def main():
with TestService(async=False) as service:
# Start CallbackServer for CallbackObjects
with CallbackServer():
callback1 = LogObject("Callback1")
callback2 = LogObject("Callback2")
# normal callback
service.callback(callback1.log)
# normal function call
callback1.log()
callback2.log()
# register for event
service.event.register(callback1.log)
service.event.register(callback2.log)
# trigger event in different ways
service.trigger_event()
service.event.trigger("Direct triggered")
service.send_message("Hallo Welt!")
# callbacks are asynchronous
# wait for them to be performed
time.sleep(0.5)
if __name__ == '__main__':
with NameServer():
with log.LogServer():
log.set_loglevel("INFO")
main()
|
Callback Service Example
callback_events/callback_service.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
CALLBACK SERVICE EXAMPLE
------------------------
Example implementation for callbacks to another service
using a CallbackService and a normal Service
.. created on 17.09.2013
.. codeauthor:: Philipp Brimmers
<P.Brimmers@yahoo.de>
'''
from __future__ import print_function, unicode_literals, division
# Built-In
import time
# External
# Internal
import PyroMP.log_server as log
from PyroMP import (callback,
CallbackService,
Event,
NameServer,
Service)
class TestService(Service):
def __init__(self, multiplex=False, async=True):
super(TestService, self).__init__(multiplex, async)
self.event = Event()
def send_message(self, msg):
# trigger event with argument
self.event.trigger(msg)
def trigger_event(self):
self.event.trigger()
class LogService(CallbackService):
"""Service which receives the callbacks
"""
def init_resources(self):
super(LogService, self).init_resources()
# register for event
with TestService(async=False) as service:
service.event.register(self.log)
def close_resources(self):
super(LogService, self).close_resources()
# unregister for event
with TestService(async=False) as service:
service.event.unregister(self.log)
@callback
def log(self, msg=None):
logger = self.get_logger()
logger.info("log(msg={!r})".format(msg))
if msg is not None:
logger.info(msg)
def main():
with TestService(async=False) as service:
with LogService():
# trigger event in different ways
service.trigger_event()
service.event.trigger("Direct triggered")
service.send_message("Hallo Welt!")
# callbacks are asynchronous
# wait for them to be performed
time.sleep(0.5)
if __name__ == '__main__':
with NameServer(), log.LogServer():
log.set_loglevel(log.INFO)
main()
|
Local Service Example
local_service/local_service.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
LOCAL SERVICE EXAMPLE
---------------------
Example implementation how to use a service as normal
python object instead of running in another process or thread
.. created on 19.02.2014
.. codeauthor:: Philipp Brimmers
<P.Brimmers@yahoo.de>
'''
from __future__ import print_function, unicode_literals, division
# built-in
import os
# Intern
import PyroMP
import PyroMP.log_server as log
class FileService(PyroMP.Service):
FILENAME = "test.txt"
def init_resources(self):
super(FileService, self).init_resources()
# create empty file
text = "LOGFILE:\n--------\n"
with open(self.FILENAME, 'w') as f:
f.write(text.encode('utf8'))
def close_resources(self):
super(FileService, self).close_resources()
# print file using logging
logger = self.get_logger()
with open(self.FILENAME, 'r') as f:
logger.info("\n" + f.read().decode('utf8'))
# delete the file
os.remove(self.FILENAME)
def write_line(self, text):
with open(self.FILENAME, 'a') as f:
f.write((text + "\n").encode('utf8'))
def main():
# disable the name server
# to prevent from using an already running one
PyroMP.NameServer.disable()
# create service object
service = FileService()
# initialize the service and create log file
service.init_resources()
# write some lines
service.write_line("first log entry")
service.write_line("second log entry")
service.write_line("third log entry")
service.write_line("special characters: *°äöüàáì€$&%")
# close the service object
# print log file and delete it
service.close_resources()
if __name__ == "__main__":
log.set_loglevel("INFO")
main()
|
Logging Window Example
qt_service/log_window.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
LOG WINDOW EXAMPLE
------------------
Additional requirements:
- PySide or PyQt4
Starts a LogServer and display all logs in a QTextEdit.
.. created on 30.12.2013
.. codeauthor:: Philipp Brimmers
<P.Brimmers@yahoo.de>
'''
from __future__ import print_function, unicode_literals, division
# Built-In
# External
from PyroMP.Qt import QtCore, QtGui
# Internal
import PyroMP
import PyroMP.log_server as log
class LogStream(object):
"""File-like object that appends the text to the LogDialog.
Used for the StreamHandler.
"""
def write(self, text):
dlg_conn = LogDialogService.get_connection(async=False)
dlg_conn.connect()
dlg_conn.append_log(text)
class LogDialog(QtGui.QDialog):
append_log_signal = QtCore.Signal(object)
def __init__(self):
super(LogDialog, self).__init__()
layout = QtGui.QVBoxLayout()
self._text_edit = QtGui.QTextEdit()
self._text_edit.setReadOnly(True)
self._text_edit.setFont("Courier New")
layout.addWidget(self._text_edit)
self.setLayout(layout)
self.append_log_signal.connect(self.append_log)
self.setWindowTitle("Log Window")
def append_log(self, text):
text = self._text_edit.toPlainText() + text
self._text_edit.setPlainText(text)
class LogDialogService(PyroMP.QtService):
LOGGING = False
def qt_main(self):
"""Create the gui elements
"""
logger = self.get_logger()
logger.debug("Create dialog")
self._dlg = LogDialog()
logger.debug("Show dialog")
# QtService without any window will be stopped
self._dlg.show()
# Configure logging for log server loggers
root_logger = log.get_server_root_logger()
log_stream = LogStream()
root_logger.add_streamhandler(log_stream)
def append_log(self, text):
# Signal is used instead of function call
# normal calls are not possible because Qt has problems with threads
self._dlg.append_log_signal.emit(text)
def main():
with LogDialogService():
LogDialogService.wait_for()
if __name__ == '__main__':
with PyroMP.NameServer(), log.LogServer():
main()
|
Matplotlib Example
plotting/matplotlib_example.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
MATPLOTLIB EXAMPLE
------------------
Additional requirements:
- PySide
- numpy
- matplotlib
Plots some random numbers using matplotlib.
.. created on 27.01.2014
.. codeauthor:: Philipp Brimmers
<P.Brimmers@yahoo.de>
'''
from __future__ import print_function, unicode_literals, division
# Built-In
import time
# External
from numpy.random import normal
import PyroMP
import PyroMP.log_server as log
from PySide.QtCore import Signal
from PySide.QtGui import QDialog, QVBoxLayout
import matplotlib
# force matplotlib to use PySide
matplotlib.rcParams['backend.qt4'] = 'PySide'
if not matplotlib.get_backend() == 'Qt4Agg':
matplotlib.use('Qt4Agg')
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
class MatplotlibDialog(QDialog):
add_value = Signal(object)
def __init__(self):
super(MatplotlibDialog, self).__init__()
# create matplotlib gui elements
# 8 inches wide and 6 inches high with a resolution of 80 dpi
size = (8, 6) # inch
dpi = 80
self._create_gui(size, dpi)
# create the axes
# use add_subplot instead of add_axis to enable subplot toolbox
self._axes = self._fig.add_subplot(111)
self._axes.set_xlabel("x-axis")
self._axes.set_ylabel("gaussian distribution (mean=6, variance=0.04)")
self.add_value.connect(self._add_value)
self._x_value = 0
self.setWindowTitle("matplotlib example")
def _create_gui(self, size, dpi):
# create figure
self._fig = Figure(size, dpi=dpi)
# create canvas widget
self._canvas = FigureCanvas(self._fig)
# create toolbar widget and connect it to canvas
mpl_toolbar = NavigationToolbar(self._canvas, self)
layout = QVBoxLayout()
layout.addWidget(mpl_toolbar)
layout.addWidget(self._canvas)
self.setLayout(layout)
def _add_value(self, value):
self._axes.scatter([self._x_value], [value])
self._canvas.draw()
self._x_value += 1
class PlotService(PyroMP.QtService):
def qt_main(self):
"""Create the gui
"""
self._dlg = MatplotlibDialog()
# show the empty window
# QtService without any window will be stopped
self._dlg.show()
def add_value(self, value):
"""Adds an additional point to the plot
"""
# Signal is used instead of function call
# normal calls are not possible because Qt has problems with threads
self._dlg.add_value.emit(value)
def main():
# start NameServer and LogServer
with PyroMP.NameServer(), log.LogServer():
# start PlotService
with PlotService(async=False) as service:
# loop until window is closed
while PlotService.is_running():
# create Random value
mean = 6
std_dev = 0.2
data_point = normal(mean, std_dev)
# plot value
service.add_value(data_point)
# wait one second
time.sleep(1)
if __name__ == "__main__":
main()
|
PyQtGraph Example
plotting/pyqtgraph_example.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
PYQTGRAPH EXAMPLE
-----------------
Additional requirements:
- PySide
- numpy
- pyqtgraph
Plots some random numbers using pyqtgraph.
.. created on 27.01.2014
.. codeauthor:: Philipp Brimmers
<P.Brimmers@yahoo.de>
'''
from __future__ import print_function, unicode_literals, division
# Built-In
import time
# External
from numpy.random import normal
import PyroMP
import PyroMP.log_server as log
from PySide.QtCore import QObject, Signal
import pyqtgraph
class PlotWindowManager(QObject):
"""Manages the plot window
"""
# Signal is used instead of function call
# normal calls are not possible because Qt has problems with threads
add_value = Signal(object)
def __init__(self):
super(PlotWindowManager, self).__init__()
# show an empty window
# QtService without any window will be stopped
labels = {"left": ("gaussian distribution (mean=6, variance=4)", ),
"bottom": ("x-axis", )}
self._plot_window = pyqtgraph.plot(title="pyqtgraph example",
labels=labels)
self.add_value.connect(self._add_value)
self._x_pos = 0
self._old_value = None
def _add_value(self, value):
"""Adds an additional point to the plot
"""
if self._old_value is not None:
self._plot_window.plot([self._x_pos - 1, self._x_pos],
[self._old_value, value])
self._x_pos += 1
self._old_value = value
class PlotService(PyroMP.QtService):
def qt_main(self):
"""Create the gui
"""
self._window_manager = PlotWindowManager()
def add_value(self, value):
"""Adds an additional point to the plot
"""
# Signal is used instead of function call
# normal calls are not possible because Qt has problems with threads
self._window_manager.add_value.emit(value)
def main():
# start NameServer and LogServer
with PyroMP.NameServer(), log.LogServer():
# start PlotService
with PlotService(async=False) as service:
# loop until window is closed
while PlotService.is_running():
# create Random value
mean = 6
std_dev = 2
data_point = normal(mean, std_dev)
# plot value
service.add_value(data_point)
# wait one second
time.sleep(1)
if __name__ == "__main__":
main()
|
PySide PyQt Example
pyside_pyqt_combination/pyqt_service.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
PYSIDE PYQT EXAMPLE
-------------------
Additional requirements:
- PySide AND PyQt4
Send text from PySide to PyQt widget.
Start pyqt_service.py first and then pyside_service.py.
You can write text into the PySide widget and
it will be forwarded to the PyQt4 one.
.. created on 30.12.2013
.. codeauthor:: Philipp Brimmers
<P.Brimmers@yahoo.de>
'''
from __future__ import print_function, unicode_literals, division
# Built-In
# External
from PyQt4.QtGui import (QVBoxLayout,
QDialog,
QTextEdit)
from PyroMP.Qt import QtCore
# Internal
import PyroMP
import PyroMP.log_server as log
class PySideDialogService(PyroMP.QtService):
pass
class OutputDialog(QDialog):
append_log_signal = QtCore.Signal(object)
def __init__(self):
super(OutputDialog, self).__init__()
layout = QVBoxLayout()
self._text_edit = QTextEdit()
self._text_edit.setReadOnly(True)
layout.addWidget(self._text_edit)
self.setLayout(layout)
self.append_log_signal.connect(self.print_)
self.setWindowTitle("PyQt Dialog")
def print_(self, text):
self._text_edit.setPlainText(text)
class PyQtDialogService(PyroMP.QtService):
def qt_main(self):
logger = self.get_logger()
logger.debug("Create dialog")
self._dlg = OutputDialog()
logger.debug("Show dialog")
# QtService without any window will be stopped
self._dlg.show()
def print_(self, text):
# Signal is used instead of function call
# normal calls are not possible because Qt has problems with threads
self._dlg.append_log_signal.emit(text)
def main():
with PyQtDialogService():
# blocks until window is closed
PyQtDialogService.wait_for()
if __name__ == '__main__':
with PyroMP.NameServer(), log.LogServer():
main()
|
pyside_pyqt_combination/pyside_service.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
PYSIDE PYQT EXAMPLE
-------------------
Additional requirements:
- PySide AND PyQt4
Send text from PySide to PyQt widget.
Start pyqt_service.py first and then pyside_service.py.
You can write text into the PySide widget and
it will be forwarded to the PyQt4 one.
.. created on 30.12.2013
.. codeauthor:: Philipp Brimmers
<P.Brimmers@yahoo.de>
'''
from __future__ import print_function, unicode_literals, division
# Built-In
# External
from PySide.QtGui import (QVBoxLayout,
QDialog,
QTextEdit)
# Internal
import PyroMP
import PyroMP.log_server as log
class PyQtDialogService(PyroMP.QtService):
pass
class OutputDialog(QDialog):
def __init__(self):
super(OutputDialog, self).__init__()
layout = QVBoxLayout()
self._proxy = PyQtDialogService.get_connection()
self._proxy.connect()
self._text_edit = QTextEdit()
self._text_edit.textChanged.connect(self.forward_text)
layout.addWidget(self._text_edit)
self.setLayout(layout)
self.setWindowTitle("PySide Dialog")
def forward_text(self):
text = self._text_edit.toPlainText()
self._proxy.print_(text)
class PySideDialogService(PyroMP.QtService):
def qt_main(self):
logger = self.get_logger()
logger.debug("Create dialog")
self._dlg = OutputDialog()
logger.debug("Show dialog")
# QtService without any window will be stopped
self._dlg.show()
def main():
with PySideDialogService():
# blocks until window is closed
PySideDialogService.wait_for()
if __name__ == '__main__':
with PyroMP.NameServer(), log.LogServer():
main()
|
Queued Callbacks Example
callback_events/queued_callback.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
QUEUED CALLBACK EXAMPLE
-----------------------
Example implementation for callbacks with a QueuedService
to a CallbackObject
.. created on 17.09.2013
.. codeauthor:: Philipp Brimmers
<P.Brimmers@yahoo.de>
'''
from __future__ import print_function, unicode_literals, division
# Built-In
import time
# External
# Internal
import PyroMP.log_server as log
from PyroMP import (callback,
CallbackObject,
CallbackServer,
Event,
NameServer,
QueuedService,
Service)
from PyroMP.errors import ForbiddenAttributeAccessError
class FakeEvent(object):
def register(self, obj):
pass
class TestService(Service):
def __init__(self, multiplex=False, async=True):
super(TestService, self).__init__(multiplex, async)
self.event = Event()
def callback(self, callback):
# call callback function directly
callback.call("Callback test")
def send_message(self, msg):
# trigger event with argument
self.event.trigger(msg)
def trigger_event(self):
self.event.trigger()
class QueuedTestService(QueuedService):
CLASS = TestService
class LogObject(CallbackObject):
"""Object which receives the callbacks
"""
def __init__(self, name):
super(LogObject, self).__init__()
self.name = name
self.logger = log.create_logger(name)
@callback
def log(self, msg=None):
self.logger.info("log(msg={!r})".format(msg))
if msg is not None:
self.logger.info(msg)
def main():
logger = log.create_logger("MAIN")
# Start CallbackServer for CallbackObjects
with CallbackServer():
with QueuedTestService() as service:
callback1 = LogObject("Callback1")
callback2 = LogObject("Callback2")
# normal callback
service.callback(callback1.log)
# register for event
service.event.register(callback1.log)
service.event.register(callback2.log)
# trigger event in different ways
service.trigger_event()
service.sync.send_message("Hallo Welt!")
try:
# events may not be triggered directly
# in queued services
service.sync.event.trigger()
logger.error("ForbiddenAttributeAccessError was "
"NOT raised")
except ForbiddenAttributeAccessError:
logger.info("ForbiddenAttributeAccessError was "
"raised (as expected)")
try:
# only PyroMP.Event objects can be accessed
# to register and unregister
service.sync.fake_event.register(callback1.log)
logger.error("ForbiddenAttributeAccessError was "
"NOT raised")
except ForbiddenAttributeAccessError:
logger.info("ForbiddenAttributeAccessError was "
"raised (as expected)")
# callbacks are asynchronous
# wait for them to be performed
time.sleep(0.5)
if __name__ == '__main__':
with NameServer():
with log.LogServer():
log.set_loglevel(log.INFO)
main()
|
Queued Service Example
queued_service/queued_service.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
QUEUED SERVICE EXAMPLE
----------------------
How to implement an QueuedService and
how is the execution order influenced by the priorities?
The function are called in alternating order, but we expect:
- Slow operation
- Slow operation
- Slow operation
- Fast operation
- Fast operation
- Fast operation
.. created on 17.09.2013
.. codeauthor:: Philipp Brimmers
<P.Brimmers@yahoo.de>
'''
from __future__ import print_function, unicode_literals, division
# Built-in
import time
# Internal
import PyroMP.log_server as log
from PyroMP import (NameServer,
priority,
QueuedService,
Service)
class TestService(Service):
""""Service is wrapped by the QueuedService,
that manages the order of execution"""
@priority(5)
def fast_operation(self):
logger = self.get_logger()
logger.info("Fast operation")
time.sleep(1)
return 1
@priority(10)
def slow_operation(self):
logger = self.get_logger()
logger.info("Slow operation")
time.sleep(5)
return 5
class QueuedTestService(QueuedService):
CLASS = TestService
def main():
with QueuedTestService() as service:
logger = log.create_logger("MAIN")
service.slow_operation()
service.fast_operation()
service.slow_operation()
service.fast_operation()
result1 = service.slow_operation()
result2 = service.fast_operation()
logger.info("All operations started")
logger.info("Wait to finish all operations")
service.sync.stop_listener()
logger.info("Listener has stopped")
logger.info("Result1 = {} (expect 5)".format(result1.value))
logger.info("Result2 = {} (expect 1)".format(result2.value))
if __name__ == '__main__':
with NameServer():
with log.LogServer():
log.set_loglevel(log.INFO)
main()
|
QtService Example
qt_service/qt_service.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
QT SERVICE EXAMPLE
------------------
Additional requirements:
- PySide or PyQt4
Demonstrates the need of using the signal/slot
mechanism instead of normal function calls.
The control dialog can start a output window either using a threaded or
a multiplexed server.
The service provides to function to print text.
One uses normal function calls, the other forwards the
text to the function using the signal/slot mechanism.
Try it and see what happens.
.. Created on 30.12.2013
.. codeauthor:: Philipp Brimmers
<P.Brimmers@yahoo.de>
'''
from __future__ import print_function, unicode_literals, division
# Built-In
# External
# Internal
import PyroMP
import PyroMP.log_server as log
from PyroMP.Qt import QtCore, QtGui
class OutputDialog(QtGui.QDialog):
print_signal = QtCore.Signal(object)
def __init__(self):
super(OutputDialog, self).__init__()
self._text_edit = QtGui.QTextEdit()
self._text_edit.setReadOnly(True)
layout = QtGui.QHBoxLayout()
layout.addWidget(self._text_edit)
self.setLayout(layout)
self.print_signal.connect(self.print_)
self.setWindowTitle("Output")
def print_(self, text):
"""Add a new line, that contains ``text`` to the QTextEdit"""
text = self._text_edit.toPlainText() + text + "\n"
self._text_edit.setPlainText(text)
class OutputDialogService(PyroMP.QtService):
def qt_main(self):
logger = self.get_logger()
logger.debug("Create dialog")
self._dlg = OutputDialog()
logger.debug("Show dialog")
# QtService without any window will be stopped
self._dlg.show()
def print_with_signal(self, text):
"""emits a signal, that calls the print_ function"""
self._dlg.print_signal.emit(text)
def print_with_function_call(self, text):
"""calls print_ function directly"""
self._dlg.print_(text)
class ControlDialog(QtGui.QDialog):
def __init__(self):
super(ControlDialog, self).__init__()
layout = QtGui.QVBoxLayout()
control_layout = QtGui.QHBoxLayout()
self._start_button = QtGui.QPushButton("Start")
self._start_button.clicked.connect(self.start_output_dialog_service)
control_layout.addWidget(self._start_button)
self._server_mode_box = QtGui.QComboBox()
self._server_mode_box.addItems(["threaded",
"multiplexed"])
control_layout.addWidget(self._server_mode_box)
self._stop_button = QtGui.QPushButton("Stop")
self._stop_button.setDisabled(True)
self._stop_button.clicked.connect(self.stop_output_dialog_service)
control_layout.addWidget(self._stop_button)
layout.addLayout(control_layout)
self._text_edit = QtGui.QLineEdit()
layout.addWidget(self._text_edit)
self.setLayout(layout)
send_layout = QtGui.QHBoxLayout()
self._send_button = QtGui.QPushButton("Send (function call)")
self._send_button.setDisabled(True)
self._send_button.clicked.connect(self.print_with_function_call)
send_layout.addWidget(self._send_button)
self._send_signal_button = QtGui.QPushButton("Send (signal/slot)")
self._send_signal_button.setDisabled(True)
self._send_signal_button.clicked.connect(self.print_with_signal)
send_layout.addWidget(self._send_signal_button)
layout.addLayout(send_layout)
self.setWindowTitle("Control Dialog")
def print_with_signal(self):
text = self._text_edit.text()
dlg_conn = OutputDialogService.get_connection(async=False)
dlg_conn.connect()
dlg_conn.print_with_signal(text)
self._text_edit.clear()
def print_with_function_call(self):
text = self._text_edit.text()
dlg_conn = OutputDialogService.get_connection(async=False)
dlg_conn.connect()
dlg_conn.print_with_function_call(text)
self._text_edit.clear()
def start_output_dialog_service(self):
# Disable buttons
self._start_button.setDisabled(True)
self._server_mode_box.setDisabled(True)
# Stop service
QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))
multiplex = self._server_mode_box.currentIndex() == 1
try:
OutputDialogService.start(multiplex)
finally:
QtGui.QApplication.restoreOverrideCursor()
# Enable buttons
self._stop_button.setEnabled(True)
self._send_button.setEnabled(True)
self._send_signal_button.setEnabled(True)
def stop_output_dialog_service(self):
# Disable buttons
self._stop_button.setDisabled(True)
self._send_button.setDisabled(True)
self._send_signal_button.setDisabled(True)
# Stop service
QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))
try:
OutputDialogService.stop()
finally:
QtGui.QApplication.restoreOverrideCursor()
# Enable buttons
self._start_button.setEnabled(True)
self._server_mode_box.setEnabled(True)
def main():
app = QtGui.QApplication([])
dialog = ControlDialog()
dialog.show()
app.exec_()
if __name__ == '__main__':
with PyroMP.NameServer(), log.LogServer():
main()
|