runtimegui.py
Go to the documentation of this file.
1 '''
2  Copyright (C) 1997-2017 JDERobot Developers Team
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU Library General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, see <http://www.gnu.org/licenses/>.
16 
17  Authors : Okan Asik (asik.okan@gmail.com)
18 
19  '''
20 from PyQt5.QtCore import Qt, pyqtSignal
21 from PyQt5.QtGui import QPainter, QPixmap
22 from PyQt5.QtWidgets import QMainWindow, QDockWidget, QTreeView, QGraphicsView, \
23  QWidget, QLabel, QVBoxLayout, QPushButton, QGraphicsItem, \
24  QGraphicsScene
25 from visualstates.gui.tree.treemodel import TreeModel
26 from visualstates.core.state import State
27 from visualstates.core.transition import Transition
28 from visualstates.configs.rospackage import getPackagePath
29 
30 
31 class RunTimeGui(QMainWindow):
32 
33  activeStateChanged = pyqtSignal(int)
34  runningStateChanged = pyqtSignal(int)
35  loadFromRoot = pyqtSignal(int)
36 
37  def __init__(self, parent=None):
38  super(QMainWindow, self).__init__()
39 
40  self.setWindowTitle("VisualStates RunTime GUI")
41 
42  self.rootState = None
43 
44  # create status bar
45  self.statusBar()
46 
47  self.createTreeView()
48  self.createStateCanvas()
49 
50  self.setGeometry(0, 0, 800, 600)
51  self.show()
52 
53  self.states = {}
54  self.transitions = {}
55 
56  self.activeState = None
57 
58  self.activeStateChanged.connect(self.activeStateChangedHandle)
59  self.runningStateChanged.connect(self.runningStateChangedHandle)
60  self.loadFromRoot.connect(self.loadFromRootHandle)
61 
62  def createTreeView(self):
63  dockWidget = QDockWidget()
64  dockWidget.setAllowedAreas(Qt.LeftDockWidgetArea)
65  dockWidget.setFeatures(QDockWidget.NoDockWidgetFeatures)
66  dockWidget.setTitleBarWidget(QWidget())
67  self.treeView = QTreeView()
68  self.treeView.clicked.connect(self.treeItemClicked)
69  self.treeModel = TreeModel()
70  self.treeView.setModel(self.treeModel)
71 
72  self.logo = QLabel()
73  logoPixmap = QPixmap(getPackagePath() + '/share/resources/jderobot.png')
74  self.logo.setPixmap(logoPixmap)
75 
76  self.upButton = QPushButton()
77  self.upButton.setText('Up')
78  self.upButton.clicked.connect(self.upButtonClicked)
79 
80  leftContainer = QWidget()
81  leftLayout = QVBoxLayout()
82  leftLayout.addWidget(self.treeView)
83  leftLayout.addWidget(self.upButton)
84  leftLayout.addWidget(self.logo)
85  leftContainer.setLayout(leftLayout)
86 
87  dockWidget.setWidget(leftContainer)
88  self.addDockWidget(Qt.LeftDockWidgetArea, dockWidget)
89 
90  def createStateCanvas(self):
91  self.stateCanvas = QGraphicsView()
92  self.scene = QGraphicsScene()
93  self.scene.setSceneRect(0, 0, 2000, 2000)
94 
95  self.setCentralWidget(self.stateCanvas)
96  self.stateCanvas.setScene(self.scene)
97  self.stateCanvas.setRenderHint(QPainter.Antialiasing)
98  # self.scene.mouseDoubleClicked.connect(self.onMouseDoubleClick)
99 
100  def addState(self, id, name, initial, x, y, parentId):
101  if parentId is not None:
102  #print('parentId:' + str(parentId) + ' parent:' + str(self.states[parentId]))
103  self.states[id] = State(id, name, initial, None, self.states[parentId])
104  self.states[parentId].addChild(self.states[id])
105  # self.states[id].parent = self.states[parentId]
106  # parentItem = self.treeModel.getByDataId(parentId)
107  # print('parent:' + str(parentItem))
108  # print('state[' + str(id) + '].parent=' + str(self.states[id].parent.id))
109  else:
110  self.states[id] = State(id, name, initial, None)
111  if id == 0:
112  self.rootState = self.states[id]
113 
114  self.states[id].setPos(x, y)
115 
116  def addTransition(self, id, name, originId, destinationId, x, y):
117  self.transitions[id] = Transition(id, name, self.states[originId], self.states[destinationId])
118  self.transitions[id].setPos(x, y)
119 
120  def emitRunningStateById(self, id):
121  self.runningStateChanged.emit(id)
122  # if self.activeState is None:
123  # return
124  # # check whether we need to change the running state according to the active state
125  # if id in self.states:
126  # if self.states[id].parent is not None:
127  # if self.states[id].parent.id == self.activeState.id:
128  # self.runningStateChanged.emit(id)
129 
131  if id not in self.states:
132  return
133  if self.states[id].parent is None:
134  return
135 
136  updateScene = False
137  if self.activeState is not None and self.states[id].parent is not None:
138  if self.states[id].parent.id == self.activeState.id:
139  updateScene = True
140 
141  for childState in self.states[id].parent.getChildren():
142  if childState.getRunning() and childState.id != id:
143  childState.setRunning(False)
144  if updateScene:
145  self.removeStateGraphicsItem(childState)
146  self.addStateGraphicsItem(childState)
147  elif childState.id == id:
148  childState.setRunning(True)
149  if updateScene:
150  self.removeStateGraphicsItem(childState)
151  self.addStateGraphicsItem(childState)
152 
153  if self.states[id].parent is not None:
154  self.treeModel.setAllBackgroundByParentId(Qt.white, self.states[id].parent.id)
155  self.treeModel.setBackgroundById(id, Qt.green)
156 
157  def emitActiveStateById(self, id):
158  self.activeStateChanged.emit(id)
159 
161  if id is None:
162  return
163  if id not in self.states:
164  return
165  if self.activeState is not None:
166  if self.activeState.id == id:
167  return
168  else:
169  self.scene.clear()
170  # invalidate current active state graphics object
171  for childState in self.activeState.getChildren():
172  childState.resetGraphicsItem()
173  for childTransition in childState.getOriginTransitions():
174  childTransition.resetGraphicsItem()
175 
176  self.activeState = self.states[id]
177 
178  for childState in self.activeState.getChildren():
179  self.addStateGraphicsItem(childState)
180  for childTransition in childState.getOriginTransitions():
181  gtItem = childTransition.getGraphicsItem()
182  gtItem.disableInteraction()
183  self.scene.addItem(gtItem)
184 
185  def emitLoadFromRoot(self):
186  self.loadFromRoot.emit(0)
187 
188  def loadFromRootHandle(self, id):
189  self.treeModel.loadFromRoot(self.states[id])
190  self.states[id].setRunning(True)
191  for child in self.states[id].getChildren():
192  if child.initial:
193  child.setRunning(True)
194  self.treeModel.setBackgroundById(child.id, Qt.green)
195  return
196 
197  def stateDoubleClicked(self, stateGraphicsItem):
198  if len(stateGraphicsItem.stateData.getChildren()) > 0:
199  self.emitActiveStateById(stateGraphicsItem.stateData.id)
200 
201  def upButtonClicked(self):
202  if self.activeState is not None:
203  if self.activeState.parent is not None:
204  self.emitActiveStateById(self.activeState.parent.id)
205 
206  def getStateById(self,state, id):
207  if state.id == id:
208  return state
209  else:
210  result = None
211  for child in state.getChildren():
212  result = self.getStateById(child, id)
213  if result is not None:
214  return result
215  return result
216 
217  def treeItemClicked(self, index):
218  id = index.internalPointer().id
219  if id in self.states:
220  if len(self.states[id].getChildren()) > 0:
221  self.emitActiveStateById(index.internalPointer().id)
222 
223  def getStateList(self, state, stateList):
224  if len(state.getChildren()) > 0:
225  stateList.append(state)
226 
227  for s in state.getChildren():
228  self.getStateList(s, stateList)
229 
230  def addStateGraphicsItem(self, state):
231  gsItem = state.getGraphicsItem()
232  gsItem.setAcceptHoverEvents(False)
233  gsItem.setFlag(QGraphicsItem.ItemIsMovable, False)
234  gsItem.doubleClicked.connect(self.stateDoubleClicked)
235  gsItem.disableInteraction()
236  self.scene.addItem(gsItem)
237 
238  def removeStateGraphicsItem(self, state):
239  gsItem = state.getGraphicsItem()
240  if gsItem in self.scene.items():
241  gsItem.doubleClicked.disconnect()
242  self.scene.removeItem(gsItem)
243  state.resetGraphicsItem()
def addTransition(self, id, name, originId, destinationId, x, y)
Definition: runtimegui.py:116
def addState(self, id, name, initial, x, y, parentId)
Definition: runtimegui.py:100


visualstates
Author(s):
autogenerated on Thu Apr 1 2021 02:42:20