2

I'm drawing a line between two widgets (two push buttons) into a graphics view with their positions as reference. But the line is drawn in a wrong place.

I tried using functions like mapToGlobal or mapToParent with different results, but it's still wrong. In the same class I have another method that draws lines with the mouse, and it works ok. I was taking it like a reference, but it seems that the events position has a different coordinate system. I don't know why this is happening.

The buttons and the graphics view are inside a Widget, which is also inside a window.

Here it is the class:

from PyQt4 import QtGui, QtCore

class WiringGraphicsView(QtGui.QGraphicsView):

    def __init__(self, parent):
        QtGui.QGraphicsView.__init__(self, parent)
        self.setScene(QtGui.QGraphicsScene(self))
        #self.setSceneRect(QtCore.QRectF(self.viewport().rect()))

    def mousePressEvent(self, event):
        self._start = event.pos()

    def mouseReleaseEvent(self, event):
        start = QtCore.QPointF(self.mapToScene(self._start))
        end = QtCore.QPointF(self.mapToScene(event.pos()))
        brush = QtGui.QBrush(QtGui.QColor(255, 0, 0) )
        pen = QtGui.QPen(brush, 2)
        line = QtGui.QGraphicsLineItem(QtCore.QLineF(start, end))
        line.setPen(pen)
        self.scene().addItem( line )

    def paintWire(self, start_widget,  end_widget):
        start_position = QtCore.QPointF(self.mapToScene(start_widget.pos()))
        end_position = QtCore.QPointF(self.mapToScene(end_widget.pos()))
        brush = QtGui.QBrush(QtGui.QColor(255, 0, 0) )
        pen = QtGui.QPen(brush, 2)
        line = QtGui.QGraphicsLineItem(QtCore.QLineF(start_position, end_position))
        line.setPen(pen)
        self.scene().addItem( line )

Current Drawing

UPDATE: At this point I've tried several things: Since the buttons were contained in a QWidget object, I take them out from there. I put them in a GroupBox instead. Also tried without containers. I don't get satisfactory results. Honestly I don't know how to do this properly considering that I'm using Qt designer and creating class files for "promoted" widgets (in this case is the GraphicsView) and set up some properties using the UpdateUi method in the main file

UPDATE 2: Here it is the file where the application is loaded:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import ui_wolfsonmixerwindow

class WolfsonMixerWindow(QMainWindow, ui_wolfsonmixerwindow.Ui_WolfsonMixerWindow):

      def __init__(self,  parent=None):
         super(WolfsonMixerWindow,  self).__init__(parent)
         self.setupUi(self)
         self.updateUi()


      def updateUi(self):
          #self.btn_AIF1RX1.setText("Hola")

          menu_plugin = QMenu()
          menu_unplug = QMenu()

          menu_plugin.addAction('Action 1', self.plugin )
          self.btn_AIF1RX1_2.setMenu(menu_plugin)

          self.btn_AIF1TX1_5.setAllowDrag(False)
          self.btn_AIF1TX1_5.setMenu(menu_unplug)



          start = self.btn_AIF1RX1_2
          end = self.btn_AIF1TX1_5

          #self.graphicsView.scene().addWidget(self.btn_AIF1RX1_2)
          #self.graphicsView.scene().addWidget(self.btn_AIF1TX1_5)
          #self.graphicsView.setWidgets(start, end)

           #HERE I CALL THE PAINTWIRE METHOD
          self.graphicsView.paintWire(start, end)


if __name__ == "__main__":
  import sys
  app = QApplication(sys.argv)
  form = WolfsonMixerWindow()
  form.show()
  app.exec_()

And the uic file:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'ui_wolfsonmixerwindow.ui'
#
# Created: Thu Feb 19 21:51:35 2015
#      by: PyQt4 UI code generator 4.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_WolfsonMixerWindow(object):
    def setupUi(self, WolfsonMixerWindow):
        WolfsonMixerWindow.setObjectName(_fromUtf8("WolfsonMixerWindow"))
        WolfsonMixerWindow.resize(562, 480)
        self.centralwidget = QtGui.QWidget(WolfsonMixerWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.gridLayoutWidget = QtGui.QWidget(self.centralwidget)
        self.gridLayoutWidget.setGeometry(QtCore.QRect(200, 10, 241, 101))
        self.gridLayoutWidget.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.gridLayoutWidget.setObjectName(_fromUtf8("gridLayoutWidget"))
        self.gridLayout = QtGui.QGridLayout(self.gridLayoutWidget)
        self.gridLayout.setSizeConstraint(QtGui.QLayout.SetMaximumSize)
        self.gridLayout.setMargin(0)
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
        self.QHBox_Playback = QtGui.QHBoxLayout()
        self.QHBox_Playback.setObjectName(_fromUtf8("QHBox_Playback"))
        self.verticalLayout = QtGui.QVBoxLayout()
        self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
        self.label_2 = QtGui.QLabel(self.gridLayoutWidget)
        self.label_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.label_2.setAlignment(QtCore.Qt.AlignCenter)
        self.label_2.setObjectName(_fromUtf8("label_2"))
        self.verticalLayout.addWidget(self.label_2)
        self.label = QtGui.QLabel(self.gridLayoutWidget)
        self.label.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName(_fromUtf8("label"))
        self.verticalLayout.addWidget(self.label)
        self.btn_AIF1RX1 = DragButton(self.gridLayoutWidget)
        self.btn_AIF1RX1.setBaseSize(QtCore.QSize(0, 0))
        self.btn_AIF1RX1.setMouseTracking(True)
        self.btn_AIF1RX1.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1RX1.setText(_fromUtf8(""))
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/audio-input-line.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.btn_AIF1RX1.setIcon(icon)
        self.btn_AIF1RX1.setAutoDefault(False)
        self.btn_AIF1RX1.setDefault(False)
        self.btn_AIF1RX1.setFlat(True)
        self.btn_AIF1RX1.setObjectName(_fromUtf8("btn_AIF1RX1"))
        self.verticalLayout.addWidget(self.btn_AIF1RX1)
        self.QHBox_Playback.addLayout(self.verticalLayout)
        self.verticalLayout_2 = QtGui.QVBoxLayout()
        self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
        self.label_3 = QtGui.QLabel(self.gridLayoutWidget)
        self.label_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.label_3.setAlignment(QtCore.Qt.AlignCenter)
        self.label_3.setObjectName(_fromUtf8("label_3"))
        self.verticalLayout_2.addWidget(self.label_3)
        self.label_4 = QtGui.QLabel(self.gridLayoutWidget)
        self.label_4.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.label_4.setAlignment(QtCore.Qt.AlignCenter)
        self.label_4.setObjectName(_fromUtf8("label_4"))
        self.verticalLayout_2.addWidget(self.label_4)
        self.btn_AIF1RX2 = QtGui.QPushButton(self.gridLayoutWidget)
        self.btn_AIF1RX2.setBaseSize(QtCore.QSize(0, 0))
        self.btn_AIF1RX2.setMouseTracking(True)
        self.btn_AIF1RX2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1RX2.setText(_fromUtf8(""))
        self.btn_AIF1RX2.setIcon(icon)
        self.btn_AIF1RX2.setAutoDefault(False)
        self.btn_AIF1RX2.setDefault(False)
        self.btn_AIF1RX2.setFlat(True)
        self.btn_AIF1RX2.setObjectName(_fromUtf8("btn_AIF1RX2"))
        self.verticalLayout_2.addWidget(self.btn_AIF1RX2)
        self.QHBox_Playback.addLayout(self.verticalLayout_2)
        self.gridLayout.addLayout(self.QHBox_Playback, 1, 0, 1, 1)
        self.horizontalLayout_3 = QtGui.QHBoxLayout()
        self.horizontalLayout_3.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
        self.horizontalLayout_3.setContentsMargins(-1, -1, 0, -1)
        self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
        self.verticalLayout_3 = QtGui.QVBoxLayout()
        self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
        self.label_6 = QtGui.QLabel(self.gridLayoutWidget)
        self.label_6.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.label_6.setAlignment(QtCore.Qt.AlignCenter)
        self.label_6.setObjectName(_fromUtf8("label_6"))
        self.verticalLayout_3.addWidget(self.label_6)
        self.label_5 = QtGui.QLabel(self.gridLayoutWidget)
        self.label_5.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.label_5.setAlignment(QtCore.Qt.AlignCenter)
        self.label_5.setObjectName(_fromUtf8("label_5"))
        self.verticalLayout_3.addWidget(self.label_5)
        self.horizontalLayout = QtGui.QHBoxLayout()
        self.horizontalLayout.setSpacing(0)
        self.horizontalLayout.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
        self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
        self.btn_AIF1TX1_1 = QtGui.QPushButton(self.gridLayoutWidget)
        self.btn_AIF1TX1_1.setMouseTracking(False)
        self.btn_AIF1TX1_1.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.btn_AIF1TX1_1.setAcceptDrops(True)
        self.btn_AIF1TX1_1.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1TX1_1.setText(_fromUtf8(""))
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/input_small.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.btn_AIF1TX1_1.setIcon(icon1)
        self.btn_AIF1TX1_1.setFlat(True)
        self.btn_AIF1TX1_1.setObjectName(_fromUtf8("btn_AIF1TX1_1"))
        self.horizontalLayout.addWidget(self.btn_AIF1TX1_1)
        self.btn_AIF1TX1_2 = QtGui.QPushButton(self.gridLayoutWidget)
        self.btn_AIF1TX1_2.setAcceptDrops(True)
        self.btn_AIF1TX1_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1TX1_2.setText(_fromUtf8(""))
        self.btn_AIF1TX1_2.setIcon(icon1)
        self.btn_AIF1TX1_2.setFlat(True)
        self.btn_AIF1TX1_2.setObjectName(_fromUtf8("btn_AIF1TX1_2"))
        self.horizontalLayout.addWidget(self.btn_AIF1TX1_2)
        self.btn_AIF1TX1_3 = QtGui.QPushButton(self.gridLayoutWidget)
        self.btn_AIF1TX1_3.setAcceptDrops(True)
        self.btn_AIF1TX1_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1TX1_3.setText(_fromUtf8(""))
        self.btn_AIF1TX1_3.setIcon(icon1)
        self.btn_AIF1TX1_3.setFlat(True)
        self.btn_AIF1TX1_3.setObjectName(_fromUtf8("btn_AIF1TX1_3"))
        self.horizontalLayout.addWidget(self.btn_AIF1TX1_3)
        self.btn_AIF1TX1_4 = QtGui.QPushButton(self.gridLayoutWidget)
        self.btn_AIF1TX1_4.setAcceptDrops(True)
        self.btn_AIF1TX1_4.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1TX1_4.setText(_fromUtf8(""))
        self.btn_AIF1TX1_4.setIcon(icon1)
        self.btn_AIF1TX1_4.setFlat(True)
        self.btn_AIF1TX1_4.setObjectName(_fromUtf8("btn_AIF1TX1_4"))
        self.horizontalLayout.addWidget(self.btn_AIF1TX1_4)
        self.verticalLayout_3.addLayout(self.horizontalLayout)
        self.horizontalLayout_3.addLayout(self.verticalLayout_3)
        self.verticalLayout_4 = QtGui.QVBoxLayout()
        self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4"))
        self.label_7 = QtGui.QLabel(self.gridLayoutWidget)
        self.label_7.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.label_7.setAlignment(QtCore.Qt.AlignCenter)
        self.label_7.setObjectName(_fromUtf8("label_7"))
        self.verticalLayout_4.addWidget(self.label_7)
        self.label_8 = QtGui.QLabel(self.gridLayoutWidget)
        self.label_8.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.label_8.setAlignment(QtCore.Qt.AlignCenter)
        self.label_8.setObjectName(_fromUtf8("label_8"))
        self.verticalLayout_4.addWidget(self.label_8)
        self.horizontalLayout_2 = QtGui.QHBoxLayout()
        self.horizontalLayout_2.setSpacing(1)
        self.horizontalLayout_2.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
        self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
        self.btn_AIF1TX2_1 = QtGui.QPushButton(self.gridLayoutWidget)
        self.btn_AIF1TX2_1.setAcceptDrops(True)
        self.btn_AIF1TX2_1.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1TX2_1.setText(_fromUtf8(""))
        self.btn_AIF1TX2_1.setIcon(icon1)
        self.btn_AIF1TX2_1.setFlat(True)
        self.btn_AIF1TX2_1.setObjectName(_fromUtf8("btn_AIF1TX2_1"))
        self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_1)
        self.btn_AIF1TX2_2 = QtGui.QPushButton(self.gridLayoutWidget)
        self.btn_AIF1TX2_2.setAcceptDrops(True)
        self.btn_AIF1TX2_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1TX2_2.setText(_fromUtf8(""))
        self.btn_AIF1TX2_2.setIcon(icon1)
        self.btn_AIF1TX2_2.setFlat(True)
        self.btn_AIF1TX2_2.setObjectName(_fromUtf8("btn_AIF1TX2_2"))
        self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_2)
        self.btn_AIF1TX2_3 = QtGui.QPushButton(self.gridLayoutWidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.btn_AIF1TX2_3.sizePolicy().hasHeightForWidth())
        self.btn_AIF1TX2_3.setSizePolicy(sizePolicy)
        self.btn_AIF1TX2_3.setAcceptDrops(True)
        self.btn_AIF1TX2_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1TX2_3.setText(_fromUtf8(""))
        self.btn_AIF1TX2_3.setIcon(icon1)
        self.btn_AIF1TX2_3.setFlat(True)
        self.btn_AIF1TX2_3.setObjectName(_fromUtf8("btn_AIF1TX2_3"))
        self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_3)
        self.btn_AIF1TX2_4 = QtGui.QPushButton(self.gridLayoutWidget)
        self.btn_AIF1TX2_4.setAcceptDrops(True)
        self.btn_AIF1TX2_4.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1TX2_4.setText(_fromUtf8(""))
        self.btn_AIF1TX2_4.setIcon(icon1)
        self.btn_AIF1TX2_4.setFlat(True)
        self.btn_AIF1TX2_4.setObjectName(_fromUtf8("btn_AIF1TX2_4"))
        self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_4)
        self.verticalLayout_4.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_3.addLayout(self.verticalLayout_4)
        self.gridLayout.addLayout(self.horizontalLayout_3, 1, 1, 1, 1)
        self.lbl_playback = QtGui.QLabel(self.gridLayoutWidget)
        self.lbl_playback.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.lbl_playback.setTextFormat(QtCore.Qt.AutoText)
        self.lbl_playback.setObjectName(_fromUtf8("lbl_playback"))
        self.gridLayout.addWidget(self.lbl_playback, 0, 0, 1, 1)
        self.label_9 = QtGui.QLabel(self.gridLayoutWidget)
        self.label_9.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.label_9.setAlignment(QtCore.Qt.AlignCenter)
        self.label_9.setObjectName(_fromUtf8("label_9"))
        self.gridLayout.addWidget(self.label_9, 0, 1, 1, 1)
        self.dial = QtGui.QDial(self.centralwidget)
        self.dial.setGeometry(QtCore.QRect(30, 360, 50, 64))
        self.dial.setObjectName(_fromUtf8("dial"))
        self.label_10 = QtGui.QLabel(self.centralwidget)
        self.label_10.setGeometry(QtCore.QRect(20, 320, 52, 15))
        self.label_10.setObjectName(_fromUtf8("label_10"))
        self.widget = QtGui.QWidget(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(160, 400, 331, 21))
        self.widget.setObjectName(_fromUtf8("widget"))
        self.groupBox = QtGui.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(130, 130, 361, 271))
        self.groupBox.setObjectName(_fromUtf8("groupBox"))
        self.graphicsView = WiringGraphicsView(self.groupBox)
        self.graphicsView.setGeometry(QtCore.QRect(40, 30, 291, 241))
        self.graphicsView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.graphicsView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
        brush.setStyle(QtCore.Qt.NoBrush)
        self.graphicsView.setBackgroundBrush(brush)
        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
        self.btn_AIF1RX1_2 = DragButton(self.groupBox)
        self.btn_AIF1RX1_2.setGeometry(QtCore.QRect(50, 50, 51, 31))
        self.btn_AIF1RX1_2.setBaseSize(QtCore.QSize(0, 0))
        self.btn_AIF1RX1_2.setMouseTracking(True)
        self.btn_AIF1RX1_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1RX1_2.setText(_fromUtf8(""))
        self.btn_AIF1RX1_2.setIcon(icon)
        self.btn_AIF1RX1_2.setAutoDefault(False)
        self.btn_AIF1RX1_2.setDefault(False)
        self.btn_AIF1RX1_2.setFlat(True)
        self.btn_AIF1RX1_2.setObjectName(_fromUtf8("btn_AIF1RX1_2"))
        self.btn_AIF1TX1_5 = DragButton(self.groupBox)
        self.btn_AIF1TX1_5.setGeometry(QtCore.QRect(270, 150, 41, 31))
        self.btn_AIF1TX1_5.setMouseTracking(False)
        self.btn_AIF1TX1_5.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.btn_AIF1TX1_5.setAcceptDrops(True)
        self.btn_AIF1TX1_5.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1TX1_5.setText(_fromUtf8(""))
        self.btn_AIF1TX1_5.setIcon(icon1)
        self.btn_AIF1TX1_5.setFlat(True)
        self.btn_AIF1TX1_5.setObjectName(_fromUtf8("btn_AIF1TX1_5"))
        self.btn_AIF1RX1_3 = DragButton(self.groupBox)
        self.btn_AIF1RX1_3.setGeometry(QtCore.QRect(60, 110, 51, 27))
        self.btn_AIF1RX1_3.setBaseSize(QtCore.QSize(0, 0))
        self.btn_AIF1RX1_3.setMouseTracking(True)
        self.btn_AIF1RX1_3.setAcceptDrops(False)
        self.btn_AIF1RX1_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
        self.btn_AIF1RX1_3.setText(_fromUtf8(""))
        self.btn_AIF1RX1_3.setIcon(icon)
        self.btn_AIF1RX1_3.setAutoDefault(False)
        self.btn_AIF1RX1_3.setDefault(False)
        self.btn_AIF1RX1_3.setFlat(True)
        self.btn_AIF1RX1_3.setObjectName(_fromUtf8("btn_AIF1RX1_3"))
        WolfsonMixerWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(WolfsonMixerWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 562, 23))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        WolfsonMixerWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(WolfsonMixerWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        WolfsonMixerWindow.setStatusBar(self.statusbar)

        self.retranslateUi(WolfsonMixerWindow)
        QtCore.QObject.connect(self.dial, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.label_10.setNum)
        QtCore.QMetaObject.connectSlotsByName(WolfsonMixerWindow)

    def retranslateUi(self, WolfsonMixerWindow):
        WolfsonMixerWindow.setWindowTitle(_translate("WolfsonMixerWindow", "Wolfson Mixer", None))
        self.label_2.setText(_translate("WolfsonMixerWindow", "AIF1RX1", None))
        self.label.setText(_translate("WolfsonMixerWindow", "L", None))
        self.label_3.setText(_translate("WolfsonMixerWindow", "AIF1RX2", None))
        self.label_4.setText(_translate("WolfsonMixerWindow", "R", None))
        self.label_6.setText(_translate("WolfsonMixerWindow", "AIF1TX1", None))
        self.label_5.setText(_translate("WolfsonMixerWindow", "L", None))
        self.label_7.setText(_translate("WolfsonMixerWindow", "AIF1TX2", None))
        self.label_8.setText(_translate("WolfsonMixerWindow", "R", None))
        self.lbl_playback.setText(_translate("WolfsonMixerWindow", "<html><head/><body><p><span style=\" font-weight:600;\">Playback (from RPi)</span></p></body></html>", None))
        self.label_9.setText(_translate("WolfsonMixerWindow", "<html><head/><body><p><span style=\" font-weight:600;\">Record (to RPi)</span></p></body></html>", None))
        self.label_10.setText(_translate("WolfsonMixerWindow", "TextLabel", None))
        self.groupBox.setTitle(_translate("WolfsonMixerWindow", "GroupBox", None))

from wiringgraphicsview import WiringGraphicsView
from dragbutton import DragButton
import icons_rc
Mr_LinDowsMac
  • 2,644
  • 9
  • 56
  • 75
  • You have presented the wrong example code. The class to draw lines with the mouse is working (as you said). But this does not help with the line between the two widgets. Could you show this code? – NoDataDumpNoContribution Feb 14 '15 at 19:05
  • I don't know what exactly went wrong because there was no picture of how wrong the line is and no example code producing the wrong line but I posted a working example of drawing line between two widgets in a graphics view as an answer. – NoDataDumpNoContribution Feb 14 '15 at 19:26
  • @Trilarion Ignore the mouse events, the method that I use for this is the `paintWire`. As you can see, it receives two parameters, start_widget and end_widget (provisional names) so those are the buttons that will receive and draw line between them. – Mr_LinDowsMac Feb 16 '15 at 12:02
  • Can you show the code where you call `paintWire`? Can you show the `uic` file? Have you tried to debug this with pdb? Can you possibly draw `rect`s around each object (for testing purposes) during `paintWire` so that you can see the bounding box (and hence each objects default origin)? – g19fanatic Feb 19 '15 at 20:33
  • @g19fanatic I just added the entire uic file and the main file where i call paintWire. I've never used pdb, but I'm using eric6 IDE. – Mr_LinDowsMac Feb 20 '15 at 05:02
  • And the code for the `DragButton`? – g19fanatic Feb 20 '15 at 13:29
  • @g19fanatic I don't want to post it here because someone could mark this post as duplicated, I just posted here a particular problem. However, the code of that DragButton is at this other post: http://stackoverflow.com/q/28258050/598070 – Mr_LinDowsMac Feb 21 '15 at 02:05
  • If you add some more debugging outputs, how does the Widget position in the `paintWire` method compare to the 'mouseMoveEvent' and 'dropEvent' in your drag button? I'm willing to bet that if you replace your drag button with a simple button, it will work fine and that the drag button is causing all of your issues (possibly the drawing of a rect while moving the object). Where is the ending 'position' line relative to a DragButtons initial starting position? Possibly in the 'center' between the dragbutton's start and end positions? – g19fanatic Feb 23 '15 at 14:31
  • I'm not drawing any line when drag n drop a button yet. At this time I'm just drawing a line between btn_AIF1RX1_2 and btn_AIF1TX1_5 in a graphicsview. I already Demoted them to a regular Qpushbutton, but paintWire still drawing not properly. So, I don't think that the dragbuttons are related. – Mr_LinDowsMac Feb 23 '15 at 21:02

1 Answers1

5

Here is an example how to draw a line between two QWidgets in a QGraphicsScene. In principle it is straightforward. The rectangle of a widget can be accessed by QGraphicsProxyWidget.geometry() and is in scene coordinates. So one can draw a line based on that.

Example:

from PySide import QtGui, QtCore

app = QtGui.QApplication([])

scene = QtGui.QGraphicsScene()

# put a button into the scene and move it
button1 = QtGui.QPushButton('Button 1')
scene_button1 = scene.addWidget(button1)
r1 = scene_button1.geometry()
r1.moveTo(-100, -50)
scene_button1.setGeometry(r1)

# put another button into the scene
button2 = QtGui.QPushButton('Button 2')
scene_button2 = scene.addWidget(button2)
r2 = scene_button2.geometry()

# add a line between the centers of each rectangles
scene.addLine(r1.x() + r1.width() / 2, r1.y() + r1.height() / 2, r2.x() + r2.width() / 2, r2.y() + r2.height() / 2)

# view on the scene
view = QtGui.QGraphicsView(scene)
view.resize(300, 200)
view.show()

app.exec_()

And it looks like:

enter image description here

And now the whole with dragging because it is not that trivial. Not the QGraphicsProxyWidget but the original QWidget, seems to get the mouse move/pressed events. We simply emit a new signal (dragged) and connect it to a function that can move the button in the scene around (using the return of scene.addWidget, the QGraphicsProxyWidget which is also a QGraphicsItem). It also redraws the line between the two buttons so they stay connected.

from PySide import QtGui, QtCore

class DraggablePushButton(QtGui.QPushButton):
    """
        Extension of QPushButton that emits a dragged signal (QPointF which is the delta in movement of the mouse) as
        long as it is pressed.
    """

    dragged = QtCore.Signal(QtCore.QPointF)

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

    def mousePressEvent(self, event):
        self.position = event.globalPos()

    def mouseMoveEvent(self, event):
        # will only by called if the mouse is also pressed
        position_now = event.globalPos()
        self.dragged.emit(position_now - self.position)
        self.position = position_now

def move_scene_button1_and_redraw_line(drag):
    # move the button1 by a certain delta position and change line connecting them with it
    scene_button1.moveBy(drag.x(), drag.y())
    r1 = scene_button1.geometry()
    line_item.setLine(r1.x() + r1.width() / 2, r1.y() + r1.height() / 2, r2.x() + r2.width() / 2, r2.y() + r2.height() / 2)

app = QtGui.QApplication([])

# the graphicsscene
scene = QtGui.QGraphicsScene()
scene.setSceneRect(-150, -100, 300, 200)

# put a draggable button into the scene
button1 = DraggablePushButton('Button 1')
scene_button1 = scene.addWidget(button1)
scene_button1.setPos(-100, -50)
r1 = scene_button1.geometry()

# connect dragged events to move of scene button
button1.dragged.connect(move_scene_button1_and_redraw_line)

# put another still standing button into the scene
button2 = QtGui.QPushButton('Button 2')
scene_button2 = scene.addWidget(button2)
r2 = scene_button2.geometry()

# draw line between button1 and button2
line_item = scene.addLine(r1.x() + r1.width() / 2, r1.y() + r1.height() / 2, r2.x() + r2.width() / 2, r2.y() + r2.height() / 2)

# view on the scene
view = QtGui.QGraphicsView(scene)
view.resize(330, 220)
view.show()

app.exec_()

And it still looks like:

enter image description here

NoDataDumpNoContribution
  • 10,591
  • 9
  • 64
  • 104
  • Apparently in my case is not so simple. Maybe I forgot to say a thing: I'm using Qt designer and a pyuic generated file. That file shouldn't be edited so I use the "Promote widget" option and then create a separate class file which I posted here. I just commented mostly of the paintWire method and took a snippet of your code, the part where "# add a line between the centers of each rectangles" and still paints in a wrong place, but at least paints it in a different place. I updated the post with the image. – Mr_LinDowsMac Feb 16 '15 at 12:03
  • Now I tested by importing my custom "Dragbuttons" into your code. But for some reason i don't get the same behavior that I have when I imported to my project. The buttons just don't drag or drop as expected! At least it should create a pixmap when dragging or change the cursor icon when about to drop. Why? – Mr_LinDowsMac Feb 24 '15 at 13:12
  • @Mr_LinDowsMax I cannot say why, especially since I don't know your Dragbuttons. But I added a second example with a draggable button which keeps the line connected to the other button. It works. – NoDataDumpNoContribution Feb 24 '15 at 14:44
  • I posted the code of my Dragbutton in this post: http://stackoverflow.com/q/28258050/598070 – Mr_LinDowsMac Feb 24 '15 at 21:09
  • 1
    As my above comment says, i believe your problem completely lies with the fact that that you DragButton draws 'transparent' rects while its being moved with a right click (but not yet dropped). Trilarion's above code is a complete snippet showing I believe the action you're expecting. +1 to you @Trilarion. – g19fanatic Feb 25 '15 at 19:11
  • @g19fanatic Well, I don't think so, because I'm drawing the line before dragging any button just to see if the method works, I have not implemented any action after dropping yet. – Mr_LinDowsMac Feb 26 '15 at 06:32
  • @Trilarion I based in your code and the line is drawing fine as expected, but as I already said, I still have problems with drawing in the graphicsview included in my ui file. Since I'm considering to write the code from scratch (*sigh*) your example works good, except that the drag should be done in other way. It is not by dragging the button and dropping in other place of the graphicsView to draw a line, the button should be dropped into the other buttons only, then draw line. – Mr_LinDowsMac Feb 27 '15 at 12:21
  • @Mr_LinDowsMac I'm glad it is kind of working and I recommend to write the code from scratch without ui files anyway. I wish you all the best with your app. – NoDataDumpNoContribution Feb 27 '15 at 16:57
  • @Trilarion It will be a nightmare because I have to implement A LOT of buttons. Also, in my current design most of them are inside layouts, I don't know if I can embed entire layouts inside QgraphicsView – Mr_LinDowsMac Feb 28 '15 at 05:28
  • @Mr_LinDowsMac For that I reccommend, put all the buttons into a layout, put that layout into a QWidget, test this widget without the graphicsview, then put it into the graphics view. – NoDataDumpNoContribution Feb 28 '15 at 10:49
  • @Trilarion Mmm... I just asked that in another post if that is really possible. Well, I guess so. – Mr_LinDowsMac Feb 28 '15 at 11:01