Pyqt5实现Widget内部拖拽
在本次项目的beta迭代中,程序需要在需要在QListWidget
内实现对于添加后的测试序列,可以通过鼠标拖拽的方式来移动测试序列,方便用户操作。
允许拖拽
如果是单纯需要移动Widget内的拖拽操作,只需要设置一下Widget内的拖拽方法:
class AddTest(QtWidgets.QDialog,Ui_Add_test):
def __init__(self):
QtWidgets.QDialog.__init__(self)
Ui_Add_test.__init__(self)
self.setupUi(self)
self.setFixedSize(self.width(),self.height())
self.currentQueueList.setDragDropMode(self.currentQueueList.InternalMove)
最后一行代码 self.currentQueueList.setDragDropMode(self.currentQueueList.InternalMove)
就设置了currentQueueList
内部的拖拽模式,其中参数可以是QListWidget
的以下成员常量(在c++版本Qt中是enum常量,但是python没有常量,以整形存在):
-
NoDragDrop
,不允许拖拽 -
DragOnly
,只允许拖出 -
DropOnly
只允许拽进 -
DragDrop
允许拖出和拽进 -
InternalMove
允许内部拖拽拖拽模式设置好以后就可以在
QListWidget
内部拖拽从而改变其内部的item的顺序了。
拖拽同时执行操作
实现内部拖拽之后,item的顺序改变仅仅是客户端界面的顺序改变,实际进行测试操作的MonkeyRunner操作部分(可以理解为本软件的后端)仍需要客户端发送同时发送信息,改变后端的测试队列顺序。
在Pyqt5中,或者说在qt中,操作和函数对应着信号(signal)和槽(slot),操作发送信号到对应的槽,执行槽内对应函数。而拖拽操作从开始到结束的过程中对应着好几个槽事件,这些事件函数在QListWidget
已经写好,但是可以通过继承并重写的形式来更改内容:
-
dropEvent
拖拽结束以后触发的事件 -
dragMoveEvent
拖拽移动过程中触发的事件 -
dragEnterEvent
(从外部或内部控件)拖拽进入后触发的事件 -
dragLeaveEvent
拖拽离开当前容器控件后触发的事件
本软件需要做到拖拽结束后触发顺序改变的事件,所以选择继承QListWidget
类重写dropEvent
方法
# overload.py #
class MyCurrentQueue(QtWidgets.QListWidget):
def __init__(self,parent = None):
super(MyCurrentQueue,self).__init__(parent)
def dropEvent(self,event):
print('%d '%self.currentRow(),end = '')#用于打印拖拽前后目标item的索引值,以便观察
index1 = self.currentRow()
super(MyCurrentQueue,self).dropEvent(event)#如果不调用父类的构造方法,拖拽操作将无法正常进行
index2 = self.currentRow()
Monkey.change(index1+ 1, index2 + 1)#调用后端提供的change方法
print(self.currentRow())
由于界面代码是由qt designer生成的,将生成的代码中的
self.currentQueueList = QtWidget.QListWidget(self.groupBox)
改成
self.currentQueueList = overload.MyCurrentQueue(self.groupBox)
重新执行程序,拖拽的同时就会打印拖拽前后的拖拽目标在容器中的索引值,并调用函数改变后端队列的顺序。
如图所示。