在Python中创建拖放建模工具

时间:2017-05-04 07:42:24

标签: python modeling

我不知道怎么问这个但是这里...... [/ p>

我想创建一个定义大约10个不同对象的用户界面。

这些对象都可以相互连接。

是否有基于Python的工具可以轻松定义简单的用户界面和带有一些可拖动对象的画布。

例如。让我们说我有一个python框架来解决powerflow。我以编程方式创建网络。

现在我只想定义一些对象,每个对象都有一张小图片,将它们拖到画布上,右键单击它们来设置它们的设置。

我可以调查所有正常的python内容,但只是检查是否可能是一个可以帮助自动执行此操作的工具。

我添加了商业工具的图片。 托比

enter image description here

2 个答案:

答案 0 :(得分:2)

是否必须是原生UI?如果没有,我建议使用类似D3.js的可视化,python作为后端,使用AJAX进行通信。它比使用PyQt或PyTk实现类似功能要高效得多。

对于一些现成的开箱即用包,我不知道是否有任何。

答案 1 :(得分:1)

要完成任务,您需要将qtnodes(https://github.com/cb109/qtnodes)模块与Pyqt拖放代码组合在一起。下面的代码可能对您有所帮助,但您需要阅读qtnodes的内部代码。如果您可以妥协拖放选项,则只需使用qtnodes即可轻松构建应用程序。

您可以构建与Tobie相同的工具,但您需要使用pyside或pyqt或tkinter从头开始编写所有代码。

将下拉列表拖动到图形场景

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_())

下面的代码是拖放按钮

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()

我从堆栈溢出的所有代码溢出。通过以下链接了解更多详情。

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

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