Skip to content

Tut1 Example4

Sung-June, Lim edited this page Oct 2, 2016 · 8 revisions

File Composition for Tutorial1

_tutorials

_tutorial1

...
example4

apps

HelloCyhub.py

blocks

MainWindow.py
Cone.py

cyapp.py
cyapp_cfg.py
cymgr.py
cymgr_cfg.py
cycoord.py
cycoord_cfg.py

Application Specification

HelloCyhub.py

  • S(Slot) : 'main'의 sig_change_color signal과 'cone_view'의 on_change_color Slot을 연결
def app_spec():
    t = 'Hello Cyhub'

    B = [('main', 'MainWindow', [], {}),
         ('cone_view', 'Cone', [], {})
    ]

    C = []

    D = dict()

    R = [
        ('main', 'view', 'cone_view')
    ]

    S = [
        ('main', 'btn_change_color_random.clicked', 'cone_view', 'on_change_color_random'),
        ('main', 'sig_change_color', 'cone_view', 'on_change_color')
    ]

    return t, B, C, D, R, S

Block

MainWindow.py (Main Block)

Arguments를 가지는 Signal 생성
  • Cone Block(cone_view)의 on_change_color(r,g,b) Slot과 연결 할 sig_change_color Signal 생성
  • Signal 생성은 Slot과 달리 @pyqtSignal decorator 사용
  • 단, Signal/Slot decorator의 arguments는 string 으로 사용
    (json 방식으로 coordinator, manager와 통신하기 때문에 object를 전달 할 수 없음)
    ex) sig_change_color = pyqtSignal('int', 'int', 'int')
Layout
  • Cone 색상을 Red로 변경시킬 btn_change_color_red 버튼 생성
  • btn_change_color_red 버튼과 연결 할 on_change_color_red() Slot 생성
  • on_change_color_red() Slot에서 sig_change_color Signal emit 호출
from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSignal

from cyhub.block import Block_meta, cyhub_slot


class MainWindow(QtWidgets.QMainWindow, metaclass=Block_meta):

    sig_change_color = pyqtSignal('int', 'int', 'int')

    def __init__(self, *args, **kwds):
        super().__init__(*args, **kwds)

        self.log = QtWidgets.QTextEdit()
        self.btn_change_color_random = QtWidgets.QPushButton('Change Color (Random)', clicked=self.on_change_color_random)
        self.btn_change_color_red = QtWidgets.QPushButton('Change Color (Red)', clicked=self.on_change_color_red)

    def initialize(self):
        """
        this method is called at end of 'compose_app'
        thus, R(reference) like 'self.cone' are available from now (not available in '__init__(..)')
        """

        # Organize layout.
        cw = QtWidgets.QWidget()
        self.setCentralWidget(cw)
        cw.setLayout(QtWidgets.QHBoxLayout())
        cw.layout().addWidget(self.view.as_widget())

        widget_sig_slot = QtWidgets.QWidget()
        cw.layout().addWidget(widget_sig_slot)
        widget_sig_slot.setLayout(QtWidgets.QVBoxLayout())
        widget_sig_slot.layout().addWidget(self.log)
        widget_sig_slot.layout().addWidget(self.btn_change_color_random)
        widget_sig_slot.layout().addWidget(self.btn_change_color_red)

        # Show.
        self.show()

    @cyhub_slot()
    def on_change_color_random(self):
        s = self.log.toPlainText() + 'Color is Changed\n'
        self.log.setText(s)

    @cyhub_slot()
    def on_change_color_red(self):
        self.sig_change_color.emit(1, 0, 0)
        s = self.log.toPlainText() + 'Color is Changed to Red\n'
        self.log.setText(s)

Cone.py (Block)

Arguments를 가지는 Slot 생성
  • Slot 생성은 @cyhub_slot(...) decorator 사용
  • 단, Signal/Slot decorator의 arguments는 string 으로 사용
    (json 방식으로 coordinator, manager와 통신하기 때문에 object를 전달 할 수 없음)
    ex) @cyhub_slot('int', 'int', 'int')
from cyhub import cy_vtk
from cyhub.block import Block_meta, cyhub_slot
from random import random


class Cone(cy_vtk.Vtk_image_holder, metaclass=Block_meta):
    def __init__(self, *args, **kwds):
        super().__init__(*args, **kwds)
        self.cone = cy_vtk.actor_cone()
        self.ren.AddActor(self.cone)

    def change_color(self, r, g, b):
        self.cone.GetProperty().SetColor(r, g, b)

        # update render
        self.view._RenderWindow.Render()

    @cyhub_slot()
    def on_change_color_random(self):
        rgb = [random() for _ in range(3)]
        self.change_color(*rgb)

    @cyhub_slot('int', 'int', 'int')
    def on_change_color(self, r, g, b):
        self.change_color(r, g, b)

How to run an App

이전의 Example과 마찬가지로 Cloud 기반의 Application을 구성하기 위하여 2대의 Machine 환경이 필요합니다. 하나의 Machine에서는 Coordinator를 실행할 것이며, 다른 하나의 Machine에서는 Application을 실행 할 것입니다. 따라서, 2대의 Machine 환경에서 실행 가능하도록 환경이 구축되어 있어야 합니다.
(하지만, 편의상 Tutorial 시연을 위해 하나의 Machine에서 Coordinator와 Application 모두 실행 가능)

이전 Example에서 작성한 cycoord_cfg.py, cymgr_cfg.py, cyapp_cfg.py 파일에서 cycode_prefix의 값을 example4의 위치로 변경하면 됩니다.

cycood_cfg.py/cyapp_cfg.py
cycode_prefix = '_tutorials._tutorial1.example4'

App 실행

  • coordinator가 위치한 machine에서 cycoord.py 파일을 실행 합니다.
  • application이 위치한 machine에서 cyapp.py 파일을 실행 합니다.
  • Remote Rendering이 되고 있는 Block은 좌측 상단에 'R'이 표시 됩니다.
[Application]

[Application Log]

[Coordinator]

Clone this wiki locally