【发布时间】:2015-02-01 00:12:41
【问题描述】:
我想知道更改某些按钮的行为以执行以下操作的“最佳做法”:
我想通过点击出现一个菜单。或者,当您拖动同一个按钮时,您可以将其放在另一个按钮中,这将“绘制”一条连接它们的线。
这是一个例子: 这个想法是将这些“插孔”按钮连接到任何其他“输入”按钮。
我正在使用 Qt 设计器,我意识到按钮属性仅列出了“acceptDrops”属性,但我无法使其工作。 Signals/Slots 没有列出有关拖放的内容。
所以我认为唯一的方法是创建“自定义小部件”或通过代码“重新实现”按钮。信号/插槽可能也是一样
如果我不想修改 pyuic 生成的文件,最好的方法是什么?
更新:我尝试的方法是使用 Qt 设计器和“Promoted widgets”选项。这允许我创建单独的类文件并重新实现一些元素。我已经通过将 PushButton 提升为“DragButton”进行了测试,并为它创建了一个类:
从 PyQt4 导入 QtGui、QtCore
类 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()
我得到了一些提示,并从这篇文章中获取了 sn-ps: PyQt4 - Drag and Drop
此时,我可以拖动此按钮,并将其放到另一个相同类型中,该类型在 Qt 设计器中将“acceptDrops”属性设置为 true。 但是,我仍然想限制某些按钮的拖动(可能通过使用 UpdateUi 方法在主文件中设置),因为有些按钮仅用于接受 drop
更新 2: 现在我正在尝试编写一个类来绘制连接这些按钮的线条或“电线”。
我正在尝试在两个小部件(两个按钮)之间画一条线,并将它们的位置作为参考。但是当我尝试时,这条线画错了地方。我也尝试使用 mapToGlobal 或 mapToParent 等函数,但结果不同,但仍然错误。 在同一个类中,我有另一种用鼠标画线的方法,并且工作正常。我把它当作参考或示例,但似乎事件位置具有不同的坐标系。好吧,我不知道为什么会这样。
按钮和图形视图位于 Widget 内部,Widget 也在 Window 内部。
这里是类,我们说的方法是 从 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 )
如果有更好的实现方法,请告诉我。
【问题讨论】:
-
您能否详细说明:“我希望通过简单的点击来显示一个菜单。”和“当你拖动同一个按钮时,你可以把它放在另一个按钮上,这将“画”一条连接它们的线。“你想点击哪里?在按钮上?为什么不使用下拉菜单? “将按钮放在另一个上”是什么意思?按钮应该放在哪里?也许你可以画一个线框?
-
我认为你是对的,也许我需要一个下拉菜单,但作为一个附加功能,我需要拖动这个按钮,然后将它放到位于其他位置的任何其他类似按钮中表格。这些按钮的任何拖放都会画一条连接它们的线......或者下拉菜单中的任何选择都会做同样的事情。因此,在这些小部件的任何“线路连接”(或断开连接)之后,我还需要一种方法来捕获该事件以为其编写适当的操作。
-
@Mailerdaimon 类似这样的东西:[link]dropbox.com/s/li5xuz574r91cgz/mixerwindow.png?dl=0 这只是一个例子,GUI 将有比这更多的项目。
-
如果您将图片上传到公共服务,我可以将其添加到您的帖子中。
-
@Mailerdaimon 我在这里上传了它:i.minus.com/iwUc5wK0PNXlu.png
标签: qt python-2.7 pyqt pyqt4 qt-designer