[技术博客]Pyqt5实现Widget内部拖拽

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)

重新执行程序,拖拽的同时就会打印拖拽前后的拖拽目标在容器中的索引值,并调用函数改变后端队列的顺序。

如图所示。

posted on 2019-05-24 20:00  assem  阅读(1613)  评论(0编辑  收藏  举报