I would like to know the “best practice” to change the behavior of some buttons to do the following:
I want the menu to appear with one click. Or, when you drag the same button, you can drop it into another, and this will "draw" a line connecting them.
Here is an example:
The idea is to connect these jack buttons to any other input buttons.
I used the Qt constructor, and I understand that only acceptDrops is specified in the button properties, but I cannot get it to work. Signals / slots do not list something about drag and drop.
So, I think the only way to do this is to create a "Custom widget" or "redefine" the button by code. Perhaps the same with signals / slots
What is the best approach for this if I don't want to modify the file generated by pyuic?
UPDATE The approach I tried is to use the Qt constructor and the Advanced Widgets option. This allows me to create separate class files and override some elements. I already tested by pushing PushButton to "DragButton" and creating a class for it:
from import PyQt4 QtGui, QtCore
DragButton class (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:
I have tips and excerpts from this post: PyQt4 - Drag and Drop
At this point, I can drag this button and transfer it to another type of the same type with the acceptDrops property set to true in the Qt design. However, I still want to limit the drag and drop of some buttons (perhaps by setting the UpdateUi method in the main file), because some will only be for accepting drops
UPDATE 2: Now I'm trying to write a class that draws lines or “wires” connecting these buttons.
I am trying to draw a line between two widgets (two buttons) in a graphic element with their positions as a link. But when I try, the line is drawn in the wrong place. I also tried using features like mapToGlobal or mapToParent with different results, but still wrong. In the same class, I have another method that draws lines with the mouse and works fine. I took this as a reference or example, but it seems that the position of the events has a different coordinate system. Well, I don’t know why this is happening.
The buttons and graphical representation are inside the widget, which is also inside the window.
Here it is a class, the method we are talking about is from import PyQt4 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 )
If there is a better way to implement this, tell me.