changeset 391:a139da1f44f6

Merge
author Windel Bouwman
date Fri, 16 May 2014 12:30:10 +0200
parents 2ec730e45ea1 (current diff) b77f3290ac79 (diff)
children bb4289c84907
files
diffstat 3 files changed, 235 insertions(+), 106 deletions(-) [+]
line wrap: on
line diff
--- a/python/other/diagrameditor.py	Fri May 16 12:29:31 2014 +0200
+++ b/python/other/diagrameditor.py	Fri May 16 12:30:10 2014 +0200
@@ -1,11 +1,16 @@
 #!/usr/bin/python
 
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import sys, json, base64
+import sys
+import json
+import base64
+import os
+
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'ide'))
+
+from qtwrapper import QtGui, QtCore, QtWidgets, pyqtSignal, get_icon
+from qtwrapper import abspath, Qt
 
 from diagramitems import Connection, ResizeSelectionHandle, Block, DiagramScene, CodeBlock
-from icons import newicon, saveicon, loadicon
 import diagramitems
 
 """
@@ -15,10 +20,13 @@
  run with python 3.x as:
   $ python [thisfile.py]
 """
+
+
 def indent(lines):
    return ['   ' + line for line in lines]
 
-class ParameterDialog(QDialog):
+
+class ParameterDialog(QtWidgets.QDialog):
    def __init__(self, block, parent = None):
       super(ParameterDialog, self).__init__(parent)
       self.block = block
@@ -36,24 +44,30 @@
       self.block.code = self.codeEdit.toPlainText()
       self.close()
 
-class EditorGraphicsView(QGraphicsView):
+
+class EditorGraphicsView(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
-      QGraphicsView.__init__(self, parent)
-      self.setDragMode(QGraphicsView.RubberBandDrag)
-      self.delShort = QShortcut(QKeySequence.Delete, self)
+      super().__init__(parent)
+      self.setObjectName('Editor')
+      self.setDragMode(QtWidgets.QGraphicsView.RubberBandDrag)
+      self.delShort = QtWidgets.QShortcut(QtGui.QKeySequence.Delete, self)
       self._model = None
-      self.treeView = QTreeView()
+      self.treeView = QtWidgets.QTreeView()
       self.treeView.clicked.connect(self.itemActivated)
+
    def itemActivated(self, idx):
       b = idx.internalPointer()
       s = b.scene()
       s.clearSelection()
       b.setSelected(True)
+
    def setDiagram(self, d):
       self.setScene(d)
       self.delShort.activated.connect(d.deleteItems)
+
    def getModel(self): 
       return self._model
+
    def setModel(self, m):
       self._model = m
       if m:
@@ -70,15 +84,19 @@
             with open(self.model.filename, 'w') as f:
                f.write(json.dumps(self.model.Dict, indent=2))
    def load(self):
-      filename = QFileDialog.getOpenFileName(self)
-      if filename:
-         self.model = loadModel(filename)
+        filename = QtWidgets.QFileDialog.getOpenFileName(self)
+        if filename:
+            self.model = loadModel(filename)
+
    def newModel(self):
-      self.model = ModelHierarchyModel()
+        print('NEW')
+        self.model = ModelHierarchyModel()
+
    def goUp(self):
       if hasattr(self.diagram, 'containingBlock'):
          self.diagram = self.diagram.containingBlock.scene()
          self.zoomAll()
+
    def showCode(self):
       if self.model:
          c = self.model.gencode()
@@ -101,10 +119,12 @@
             exec(codeview.toPlainText(), globs)
          runButton.clicked.connect(runIt)
          d.exec_()
+
    def zoomAll(self):
       """ zoom to fit all items """
       rect = self.diagram.itemsBoundingRect()
       self.fitInView(rect, Qt.KeepAspectRatio)
+
    def wheelEvent(self, event):
       pos = event.pos()
       posbefore = self.mapToScene(pos)
@@ -112,11 +132,15 @@
       sx = (100.0 + degrees) / 100.0
       self.scale(sx, sx)
       event.accept()
+
    def dragEnterEvent(self, event):
-      if event.mimeData().hasFormat('component/name'):
-         event.accept()
+        if event.mimeData().hasFormat('component/name'):
+            event.accept()
+
    def dragMoveEvent(self, event):
-      if event.mimeData().hasFormat('component/name'): event.accept()
+        if event.mimeData().hasFormat('component/name'):
+            event.accept()
+
    def dropEvent(self, event):
       if event.mimeData().hasFormat('component/name'):
          name = bytes(event.mimeData().data('component/name')).decode()
@@ -132,29 +156,39 @@
          b.setPos(pos)
          s.addItem(b)
 
-class LibraryModel(QStandardItemModel):
-   mimeTypes = lambda self: ['component/name']
-   def mimeData(self, idxs):
-      mimedata = QMimeData()
-      for idx in idxs:
-         if idx.isValid():
-            txt = self.data(idx, Qt.DisplayRole)
-            mimedata.setData('component/name', txt)
-      return mimedata
+
+class LibraryModel(QtGui.QStandardItemModel):
+    def __init__(self, parent):
+        super().__init__(parent)
+        self.setObjectName('Library')
 
-class ModelHierarchyModel(QAbstractItemModel):
+    mimeTypes = lambda self: ['component/name']
+    def mimeData(self, idxs):
+        mimedata = QtCore.QMimeData()
+        for idx in idxs:
+            if idx.isValid():
+                txt = self.data(idx, Qt.DisplayRole)
+                mimedata.setData('component/name', txt)
+        return mimedata
+
+
+class ModelHierarchyModel(QtCore.QAbstractItemModel):
    def __init__(self):
       super(ModelHierarchyModel, self).__init__()
       self.rootDiagram = DiagramScene()
       self.rootDiagram.structureChanged.connect(self.handlechange)
       self.filename = None
+
    def handlechange(self):
       self.modelReset.emit()
+
    def setDict(self, d):
       self.rootDiagram.Dict = d
       self.modelReset.emit()
+
    def getDict(self):
       return self.rootDiagram.Dict
+
    Dict = property(getDict, setDict)
    def gencode(self):
       c = ['def topLevel():']
@@ -163,6 +197,7 @@
       c.append('topLevel()')
       c.append('print("Done")')
       return c
+
    def index(self, row, column, parent=None):
       if parent.isValid():
          parent = parent.internalPointer().subModel
@@ -174,6 +209,7 @@
       # TODO: solve this in a better way.
       block.index = self.createIndex(row, column, block)
       return block.index
+
    def parent(self, index):
       if index.isValid():
          block = index.internalPointer()
@@ -184,6 +220,7 @@
             outerBlock = block.scene().containingBlock
             return outerBlock.index
       print('parent: No valid index')
+
    def data(self, index, role):
       if index.isValid() and role == Qt.DisplayRole:
          b = index.internalPointer()
@@ -191,6 +228,7 @@
             return b.name
          elif index.column() == 1:
             return str(type(b))
+
    def headerData(self, section, orientation, role):
       if orientation == Qt.Horizontal and role == Qt.DisplayRole:
          if section == 0:
@@ -199,6 +237,7 @@
             return "Type"
          else:
             return "x"
+
    def rowCount(self, parent):
       if parent.column() > 0: 
          return 0
@@ -210,32 +249,37 @@
             return 0
       else:
          return len(self.rootDiagram.blocks)
+
    def columnCount(self, parent):
       return 2
 
-class LibraryWidget(QListView):
-   def __init__(self):
-      super(LibraryWidget, self).__init__(None)
+
+class LibraryWidget(QtWidgets.QListView):
+    def __init__(self):
+      super().__init__()
+      self.setObjectName('LibraryWidget')
       self.libraryModel = LibraryModel(self)
       self.libraryModel.setColumnCount(1)
       # Create an icon with an icon:
-      pixmap = QPixmap(60, 60)
+      pixmap = QtGui.QPixmap(60, 60)
       pixmap.fill()
-      painter = QPainter(pixmap)
+      painter = QtGui.QPainter(pixmap)
       painter.fillRect(10, 10, 40, 40, Qt.blue)
       painter.setBrush(Qt.yellow)
       painter.drawEllipse(20, 20, 20, 20)
       painter.end()
       # Fill library:
       for name in ['CodeBlock:codeBlock', 'DiagramBlock:submod', 'Block:blk']:
-         self.libraryModel.appendRow(QStandardItem(QIcon(pixmap), name))
+         self.libraryModel.appendRow(QtGui.QStandardItem(QtGui.QIcon(pixmap), name))
       self.setModel(self.libraryModel)
       self.setViewMode(self.IconMode)
       self.setDragDropMode(self.DragOnly)
 
+
 def warning(txt):
    QMessageBox.warning(None, "Warning", txt)
 
+
 def loadModel(filename):
    try:
       m = ModelHierarchyModel()
@@ -250,8 +294,9 @@
    except FileNotFoundError:
       warning('File [{0}] not found'.format(filename))
 
-class Main(QMainWindow):
-   def __init__(self):
+
+class Main(QtWidgets.QMainWindow):
+    def __init__(self):
       super(Main, self).__init__(None)
       self.editor = EditorGraphicsView()
       self.setCentralWidget(self.editor)
@@ -264,30 +309,32 @@
       toolbar = self.addToolBar('Tools')
       toolbar.setObjectName('Tools')
       def act(name, shortcut, callback, icon=None):
-         a = QAction(icon, name, self) if icon else QAction(name, self)
+         a = QtWidgets.QAction(icon, name, self) if icon else QtWidgets.QAction(name, self)
          a.setShortcuts(shortcut)
          a.triggered.connect(callback)
          toolbar.addAction(a)
-      act('New', QKeySequence.New, self.editor.newModel, buildIcon(newicon))
-      act('Save', QKeySequence.Save, self.editor.save, buildIcon(saveicon))
-      act('Load', QKeySequence.Open, self.editor.load, buildIcon(loadicon))
-      act('Full screen', QKeySequence("F11"), self.toggleFullScreen)
-      act('Fit in view', QKeySequence("F8"), self.editor.zoomAll)
-      act('Go up', QKeySequence(Qt.Key_Up), self.editor.goUp)
-      act('Model code', QKeySequence("F7"), self.editor.showCode)
+      act('New', QtGui.QKeySequence.New, self.editor.newModel)
+      act('Save', QtGui.QKeySequence.Save, self.editor.save)
+      act('Load', QtGui.QKeySequence.Open, self.editor.load)
+      act('Full screen', QtGui.QKeySequence("F11"), self.toggleFullScreen)
+      act('Fit in view', QtGui.QKeySequence("F8"), self.editor.zoomAll)
+      act('Go up', QtGui.QKeySequence(Qt.Key_Up), self.editor.goUp)
+      act('Model code', QtGui.QKeySequence("F7"), self.editor.showCode)
       def addDock(name, widget):
-         dock = QDockWidget(name, self)
+         dock = QtWidgets.QDockWidget(name, self)
          dock.setObjectName(name)
          dock.setWidget(widget)
          self.addDockWidget(Qt.LeftDockWidgetArea, dock)
       addDock('Library', LibraryWidget())
       addDock('Model tree', self.editor.treeView)
-      self.settings = QSettings('windelsoft', 'diagrameditor')
+      self.settings = QtCore.QSettings('windelsoft', 'diagrameditor')
       self.loadSettings()
-   def toggleFullScreen(self):
-      self.setWindowState(self.windowState() ^ Qt.WindowFullScreen)
-      self.editor.zoomAll()
-   def loadSettings(self):
+
+    def toggleFullScreen(self):
+        self.setWindowState(self.windowState() ^ Qt.WindowFullScreen)
+        self.editor.zoomAll()
+
+    def loadSettings(self):
       if self.settings.contains('mainwindowstate'):
          self.restoreState(self.settings.value('mainwindowstate'))
       if self.settings.contains('mainwindowgeometry'):
@@ -295,7 +342,8 @@
       if self.settings.contains('openedmodel'):
          modelfile = self.settings.value('openedmodel')
          self.editor.model = loadModel(modelfile)
-   def closeEvent(self, ev):
+
+    def closeEvent(self, ev):
       self.settings.setValue('mainwindowstate', self.saveState())
       self.settings.setValue('mainwindowgeometry', self.saveGeometry())
       if self.editor.model and self.editor.model.filename:
@@ -309,7 +357,7 @@
    if sys.version_info.major != 3:
       print('Please use python 3.x')
       sys.exit(1)
-   app = QApplication(sys.argv)
+   app = QtWidgets.QApplication(sys.argv)
    main = Main()
    main.show()
    app.exec_()
--- a/python/other/diagramitems.py	Fri May 16 12:29:31 2014 +0200
+++ b/python/other/diagramitems.py	Fri May 16 12:30:10 2014 +0200
@@ -2,43 +2,55 @@
  Contains all blocks that can be used to build models.
 """
 
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+import sys
+import json
+import base64
+import os
+
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'ide'))
+
+from qtwrapper import QtGui, QtCore, QtWidgets, pyqtSignal, get_icon
+from qtwrapper import abspath, Qt
+
 
 def uniqify(name, names):
-   newname, i = name, 1
-   while newname in names: newname, i = name + str(i), i + 1
-   return newname
+    newname, i = name, 1
+    while newname in names: newname, i = name + str(i), i + 1
+    return newname
+
 
 def enum(**enums):
-   return type('Enum', (), enums)
+    return type('Enum', (), enums)
+
 
 Position = enum(TOP=0, TOP_RIGHT=1, RIGHT=2, BOTTOM_RIGHT=3, BOTTOM=4, BOTTOM_LEFT=5, LEFT=6, TOP_LEFT=7)
 
+
 def buildPath(pts):
-   path = QPainterPath(pts[0])
-   for pt in pts[1:]: path.lineTo(pt)
-   return path
+    path = QtGui.QPainterPath(pts[0])
+    for pt in pts[1:]: path.lineTo(pt)
+    return path
 
 def equalSpace(n, l, offset=15):
-   if n == 1:
-      return [l / 2]
-   elif n > 1:
-      return [offset + (l - offset*2)/(n - 1)*i for i in range(n)]
-   return []
+    if n == 1:
+        return [l / 2]
+    elif n > 1:
+        return [offset + (l - offset*2)/(n - 1)*i for i in range(n)]
+    return []
 
-class Connection(QGraphicsPathItem):
+
+class Connection(QtWidgets.QGraphicsPathItem):
    """ A connection between blocks """
    def __init__(self, fromPort=None, toPort=None):
       super(Connection, self).__init__()
       self.pos2 = self.fromPort = self.toPort = None
       self.setFlags(self.ItemIsSelectable | self.ItemClipsToShape)
-      pen = QPen(Qt.blue, 2, cap=Qt.RoundCap)
+      pen = QtGui.QPen(Qt.blue, 2, cap=Qt.RoundCap)
       self.setPen(pen)
-      self.arrowhead = QGraphicsPathItem(self)
+      self.arrowhead = QtGui.QGraphicsPathItem(self)
       self.arrowhead.setPath(buildPath([QPointF(0.0, 0.0), QPointF(-6.0, 10.0), QPointF(6.0, 10.0), QPointF(0.0, 0.0)]))
       self.arrowhead.setPen(pen)
-      self.arrowhead.setBrush(QBrush(pen.color()))
+      self.arrowhead.setBrush(QtGui.QBrush(pen.color()))
       self.vias = []
       self.setFromPort(fromPort)
       self.setToPort(toPort)
@@ -99,7 +111,7 @@
       scene = self.scene()
       vias = [pos1 + QPointF(20, 0)] + self.vias + [pos2 + QPointF(-20, 0)]
       if scene:
-         litem = QGraphicsLineItem()
+         litem = QtGui.QGraphicsLineItem()
          litem.setFlags(self.ItemIsSelectable)
          scene.addItem(litem)
          for p1, p2 in zip(vias[:-1], vias[1:]):
@@ -115,19 +127,19 @@
       self.setPath(p)
       """ Create a shape outline using the path stroker """
       s = super(Connection, self).shape()
-      pps = QPainterPathStroker()
+      pps = QtGui.QPainterPathStroker()
       pps.setWidth(10)
       self.myshape = pps.createStroke(s).simplified()
 
-class PortItem(QGraphicsPathItem):
+class PortItem(QtWidgets.QGraphicsPathItem):
    """ Represents a port to a subsystem """
    def __init__(self, name, block):
       super(PortItem, self).__init__(block)
-      self.textItem = QGraphicsTextItem(self)
+      self.textItem = QtGui.QGraphicsTextItem(self)
       self.connection = None
       self.block = block
-      self.setCursor(QCursor(Qt.CrossCursor))
-      self.setPen(QPen(Qt.blue, 2, cap=Qt.RoundCap))
+      self.setCursor(QtGui.QCursor(Qt.CrossCursor))
+      self.setPen(QtGui.QPen(Qt.blue, 2, cap=Qt.RoundCap))
       self.name = name
       self.posCallbacks = []
       self.setFlag(self.ItemSendsScenePositionChanges, True)
@@ -160,15 +172,15 @@
       super(InputPort, self).__init__(name, block)
       self.setPath(buildPath([QPointF(-d, -d), QPointF(0, 0), QPointF(-d, d)]))
 
-class Handle(QGraphicsEllipseItem):
+class Handle(QtWidgets.QGraphicsEllipseItem):
    """ A handle that can be moved by the mouse """
    def __init__(self, dx=10.0, parent=None):
-      super(Handle, self).__init__(QRectF(-0.5*dx,-0.5*dx,dx,dx), parent)
-      self.setBrush(QBrush(Qt.white))
+      super(Handle, self).__init__(QtCore.QRectF(-0.5*dx,-0.5*dx,dx,dx), parent)
+      self.setBrush(QtGui.QBrush(Qt.white))
       self.setFlags(self.ItemIsMovable)
       self.setZValue(1)
       self.setVisible(False)
-      self.setCursor(QCursor(Qt.SizeFDiagCursor))
+      self.setCursor(QtGui.QCursor(Qt.SizeFDiagCursor))
    def mouseMoveEvent(self, event):
       """ Move function without moving the other selected elements """
       p = self.mapToParent(event.pos())
@@ -180,38 +192,38 @@
       self.position = position
       self.block = block
       if position in [Position.TOP_LEFT, Position.BOTTOM_RIGHT]:
-         self.setCursor(QCursor(Qt.SizeFDiagCursor))
+         self.setCursor(QtGui.QCursor(Qt.SizeFDiagCursor))
       elif position in [Position.TOP_RIGHT, Position.BOTTOM_LEFT]:
          self.setCursor(QCursor(Qt.SizeBDiagCursor))
       elif position in [Position.TOP, Position.BOTTOM]:
          self.setCursor(QCursor(Qt.SizeVerCursor))
       elif position in [Position.LEFT, Position.RIGHT]:
-         self.setCursor(QCursor(Qt.SizeHorCursor))
+         self.setCursor(QtGui.QCursor(Qt.SizeHorCursor))
    def mouseMoveEvent(self, event):
       self.block.sizerMoveEvent(self, event.scenePos())
 
-class Block(QGraphicsRectItem):
+class Block(QtWidgets.QGraphicsRectItem):
    """ Represents a block in the diagram. """
    def __init__(self, name='Untitled', parent=None):
       super(Block, self).__init__(parent)
       self.selectionHandles = [ResizeSelectionHandle(i, self) for i in range(8)]
       # Properties of the rectangle:
-      self.setPen(QPen(Qt.blue, 2))
-      self.setBrush(QBrush(Qt.lightGray))
+      self.setPen(QtGui.QPen(Qt.blue, 2))
+      self.setBrush(QtGui.QBrush(Qt.lightGray))
       self.setFlags(self.ItemIsSelectable | self.ItemIsMovable | self.ItemSendsScenePositionChanges)
-      self.setCursor(QCursor(Qt.PointingHandCursor))
+      self.setCursor(QtGui.QCursor(Qt.PointingHandCursor))
       self.setAcceptHoverEvents(True)
-      self.label = QGraphicsTextItem(name, self)
+      self.label = QtWidgets.QGraphicsTextItem(name, self)
       self.name = name
       # Create corner for resize:
-      button = QPushButton('+in')
+      button = QtWidgets.QPushButton('+in')
       button.clicked.connect(self.newInputPort)
-      self.buttonItemAddInput = QGraphicsProxyWidget(self)
+      self.buttonItemAddInput = QtWidgets.QGraphicsProxyWidget(self)
       self.buttonItemAddInput.setWidget(button)
       self.buttonItemAddInput.setVisible(False)
-      button = QPushButton('+out')
+      button = QtWidgets.QPushButton('+out')
       button.clicked.connect(self.newOutputPort)
-      self.buttonItemAddOutput = QGraphicsProxyWidget(self)
+      self.buttonItemAddOutput = QtWidgets.QGraphicsProxyWidget(self)
       self.buttonItemAddOutput.setWidget(button)
       self.buttonItemAddOutput.setVisible(False)
       # Inputs and outputs of the block:
@@ -329,18 +341,22 @@
       self.label.setPos((w - rect.width()) / 2, (h - rect.height()) / 2)
       self.updateSize()
 
+
 class CodeBlock(Block):
-   def __init__(self, name='Untitled', parent=None):
-      super(CodeBlock, self).__init__(name, parent)
-      self.code = ''
-   def setDict(self, d):
-      super(CodeBlock, self).setDict(d)
-      self.code = d['code']
-   def getDict(self):
-      d = super(CodeBlock, self).getDict()
-      d['code'] = self.code
-      return d
-   def gencode(self):
+    def __init__(self, name='Untitled', parent=None):
+        super(CodeBlock, self).__init__(name, parent)
+        self.code = ''
+
+    def setDict(self, d):
+        super(CodeBlock, self).setDict(d)
+        self.code = d['code']
+
+    def getDict(self):
+        d = super(CodeBlock, self).getDict()
+        d['code'] = self.code
+        return d
+
+    def gencode(self):
       c = ['def {0}():'.format(self.name)]
       if self.code:
          c += indent(self.code.split('\n'))
@@ -348,14 +364,17 @@
          c += indent(['pass'])
       return c
 
+
 class DiagramBlock(Block):
-   def __init__(self, name='Untitled', parent=None):
+    def __init__(self, name='Untitled', parent=None):
       super(DiagramBlock, self).__init__(name, parent)
       self.subModel = DiagramScene()
       self.subModel.containingBlock = self
-   def setDict(self, d):
-      self.subModel.Dict = d['submodel']
-   def mouseDoubleClickEvent(self, event):
+
+    def setDict(self, d):
+        self.subModel.Dict = d['submodel']
+
+    def mouseDoubleClickEvent(self, event):
       # descent into child diagram
       #self.editParameters()
       print('descent')
@@ -365,7 +384,8 @@
             view.diagram = self.subModel
             view.zoomAll()
 
-class DiagramScene(QGraphicsScene):
+
+class DiagramScene(QtWidgets.QGraphicsScene):
    """ A diagram scene consisting of blocks and connections """
    structureChanged = pyqtSignal()
    def __init__(self):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testdiagrameditor.py	Fri May 16 12:30:10 2014 +0200
@@ -0,0 +1,61 @@
+
+import unittest
+import os
+import sys
+import time
+
+try:
+    otherpath = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'python','other'))
+    sys.path.insert(0, otherpath)
+    import diagrameditor
+
+    from PyQt5.QtWidgets import QApplication
+    from PyQt5.QtTest import QTest
+    from PyQt5.QtCore import Qt, QTimer
+    skip_it = False
+
+    # When creating an app per testcase, this fails horribly..
+    app = QApplication(sys.argv)
+except ImportError as e:
+    skip_it = True
+
+
+
+class DiagramEditorTestCase(unittest.TestCase):
+    def setUp(self):
+        if skip_it:
+            self.skipTest('No qt5 or X server')
+            return
+        #print('Instance:', QApplication.instance())
+        self.main = diagrameditor.Main()
+        self.main.show()
+        QTest.qWaitForWindowActive(self.main)
+
+    def tearDown(self):
+        QTimer.singleShot(100, app.quit)
+        app.exec_()
+
+    def cmdNewModel(self):
+        # Press ctrl+N:
+        QTest.keyClick(self.main, Qt.Key_N, Qt.ControlModifier)
+
+    def dragItemIntoScene(self):
+        library = self.main.findChild(diagrameditor.LibraryWidget, 'LibraryWidget')
+        editor = self.main.findChild(diagrameditor.EditorGraphicsView, 'Editor')
+        #ilibrary.
+        QTest.mousePress(library, Qt.LeftButton)
+        print(editor, type(editor))
+        QTest.mouseMove(editor)
+        QTest.mouseRelease(editor, Qt.LeftButton)
+
+    def testScenario1(self):
+        self.cmdNewModel()
+        self.dragItemIntoScene()
+
+    def testB(self):
+        print('b')
+
+
+if __name__ == '__main__':
+    unittest.main()
+