4

I am not sure how to ask this but here goes....

I want to create a user interface that defines about 10 different objects.

These objects can all be connected to each other.

Is there is Python based tool that would make it easy to define a simple user interface and a canvas with some objects that could be dragged.

For instance. Lets say I have a python framework to solve powerflow. I create the network programatically.

Now i just want to define some objects, each with a small picture, drag them on a canvas, right click them to set their settings.

I can investigate all the normal python stuff, but is just checking if thre is not maybe a tool that could help automate this.

I add a picture of a commercial tool. Tobie

enter image description here

Tooblippe
  • 3,433
  • 3
  • 17
  • 25
  • PyQT or PySide can help you. Install PySide using PIP install PySide. Go to PySide installed folder "C:\Python27\Lib\site-packages\PySide\examples" Go through all example. examples might help you to do your task. – Bhuvan Kumar May 04 '17 at 07:51
  • HI, thanks for your answer, but I think that is exactly what I am not asking. I understand these frameworks and have used them before. My question is more related to "Is there a framework that makes building a simple modeling tool, with a drag and drop interface simple. – Tooblippe May 05 '17 at 05:13
  • Sorry, I'm unable to understand your question properly. Can you give me any example of tool which you might be looking for similar. I'm using Qt Designer which has drag and drop interface to build form, I think you are aware of Qt Designer. – Bhuvan Kumar May 05 '17 at 06:26
  • hi, the app itself will be a drag and drop interface. The app we need to build to model networks will have some equipment in a selection pane, and you should be able to drag and drop them on a canvas. connect them to each other and set their attributes. Here is an example of a js option - http://freegroup.github.io/draw2d_js.app.brainbox/. – Tooblippe May 08 '17 at 20:05
  • i have also added a screenshot from a commercial tool in my original question – Tooblippe May 08 '17 at 20:11
  • 1
    Hello @Tooblippe. Have you found a solution for your problem. I need an interface exactly what you want. – Mustafa Uçar Nov 07 '19 at 03:44

2 Answers2

4

Does it have to be a native UI? If not, I'd suggest using something like D3.js for visualization, python as backend and AJAX for communication. It will be much more efficient than implementing similar functionalities using PyQt or PyTk.

As for some ready out of the box packages, I'm not aware if there're any.

peidaqi
  • 673
  • 1
  • 7
  • 18
1

To achieve your task, you need to combine the qtnodes(https://github.com/cb109/qtnodes) module with Pyqt drag drop code. Below code might help you but you need to read the internal codes of qtnodes. If you can compromise drag drop options, it will be easy for you to build application only with qtnodes.

You can build tool same as Tobie, but you need to write all code from scratch using pyside or pyqt or tkinter.

Drag drop list to graphics Scene

from PyQt4 import QtCore, QtGui
import sys

class GraphicsScene(QtGui.QGraphicsScene):

    def __init__(self, parent = None):
        super(GraphicsScene, self).__init__(parent)

    def dragEnterEvent(self, event):
        event.accept()

    def dragMoveEvent(self, event):
        event.accept()

    def dragLeaveEvent(self, event):
        event.accept()

    def dropEvent(self, event):
        text = QtGui.QGraphicsTextItem(event.mimeData().text())
        text.setPos(event.scenePos())
        self.addItem(text)
        event.accept()

class ListView(QtGui.QListView):

    def __init__(self, parent = None):
        super(ListView, self).__init__(parent)
        self.setDragEnabled(True)

    def dragEnterEvent(self, event):
        event.setDropAction(QtCore.Qt.MoveAction)
        event.accept()

    def startDrag(self, event):
        index = self.indexAt(event.pos())
        if not index.isValid():
            return

        selected = self.model().data(index, QtCore.Qt.DisplayRole)

        mimeData = QtCore.QMimeData()
        mimeData.setText(selected.toString())

        drag = QtGui.QDrag(self)
        drag.setMimeData(mimeData)

        result = drag.start(QtCore.Qt.MoveAction)
        if result: # == QtCore.Qt.MoveAction:
            pass

    def mouseMoveEvent(self, event):
        self.startDrag(event)

class MainWindow(QtGui.QMainWindow):

    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)

        self.setGeometry(100, 100, 400, 400)

        self.widget = QtGui.QWidget()
        self.setCentralWidget(self.widget)
        layout = QtGui.QGridLayout(self.widget)

        self.ListView = ListView()

        data = QtCore.QStringList()
        data << "one" << "two" << "three"
        self.model = QtGui.QStringListModel(data)
        

        self.ListView.setModel(self.model)

        self.GraphicsView = QtGui.QGraphicsView()
        self.scene = GraphicsScene()
        self.GraphicsView.setScene(self.scene)
        #self.GraphicsView.setSceneRect(0, 0, self.GraphicsView.width(), self.GraphicsView.height())
        
        layout.addWidget(self.ListView, 0, 0, 5, 5)
        layout.addWidget(self.GraphicsView, 0, 1, 5, 5)

        self.show()
        self.GraphicsView.setSceneRect(0, 0, self.GraphicsView.width(), self.GraphicsView.height())

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec_())

Below code is for drag and drop of buttons

from PyQt4 import QtGui, QtCore

class DragButton(QtGui.QPushButton):

    def __init__(self, parent):
         super(DragButton,  self).__init__(parent)
         self.allowDrag = True
    
    def setAllowDrag(self, allowDrag):
        if type(allowDrag) == bool:
           self.allowDrag = allowDrag
        else:
            raise TypeError("You have to set a boolean type")
    
    def mouseMoveEvent(self, e):
        if e.buttons() != QtCore.Qt.RightButton:
            return
    
        if self.allowDrag == True:
            # write the relative cursor position to mime data
            mimeData = QtCore.QMimeData()
            # simple string with 'x,y'
            mimeData.setText('%d,%d' % (e.x(), e.y()))
            print mimeData.text()
    
            # let's make it fancy. we'll show a "ghost" of the button as we drag
            # grab the button to a pixmap
            pixmap = QtGui.QPixmap.grabWidget(self)
    
            # below makes the pixmap half transparent
            painter = QtGui.QPainter(pixmap)
            painter.setCompositionMode(painter.CompositionMode_DestinationIn)
            painter.fillRect(pixmap.rect(), QtGui.QColor(0, 0, 0, 127))
            painter.end()
    
            # make a QDrag
            drag = QtGui.QDrag(self)
            # put our MimeData
            drag.setMimeData(mimeData)
            # set its Pixmap
            drag.setPixmap(pixmap)
            # shift the Pixmap so that it coincides with the cursor position
            drag.setHotSpot(e.pos())
    
            # start the drag operation
            # exec_ will return the accepted action from dropEvent
            if drag.exec_(QtCore.Qt.LinkAction | QtCore.Qt.MoveAction) == QtCore.Qt.LinkAction:
                print 'linked'
            else:
                print 'moved'
    
    def mousePressEvent(self, e):
        QtGui.QPushButton.mousePressEvent(self, e)
        if e.button() == QtCore.Qt.LeftButton:
            print 'press'
            #AQUI DEBO IMPLEMENTAR EL MENU CONTEXTUAL
    
    def dragEnterEvent(self, e):
        e.accept()
    
    def dropEvent(self, e):
        # get the relative position from the mime data
        mime = e.mimeData().text()
        x, y = map(int, mime.split(','))
    
            # move
            # so move the dragged button (i.e. event.source())
        print e.pos()
            #e.source().move(e.pos()-QtCore.QPoint(x, y))
            # set the drop action as LinkAction
        e.setDropAction(QtCore.Qt.LinkAction)
        # tell the QDrag we accepted it
        e.accept()

All the codes i have copied from stack overflow. Go through links below for more details.

Drag n Drop inside QgraphicsView doesn't work (PyQt)

Drag n Drop Button and Drop-down menu PyQt/Qt designer

Community
  • 1
  • 1
Bhuvan Kumar
  • 554
  • 1
  • 7
  • 23