pyqt5按钮拖拽,实现拖拽新增和拖拽移动

pyqt5按钮拖拽,实现拖拽新增和拖拽移动

按钮默认不能拖动,需要重新按钮类,我们的需求是按钮拖动复制和单纯的拖动,所以需要重写两个类

按钮拖动复制

class MyPushButton(QPushButton):

    def __init__(self, parent=None, text=''):
        super(MyPushButton, self).__init__(parent)
        self.text = text
        self.setText(text)

    def mouseMoveEvent(self, e):
        if e.buttons() != Qt.LeftButton:
            return
        mimeData = QMimeData()
        mimeData.setText('add,' + self.text)
        drag = QDrag(self)
        drag.setMimeData(mimeData)
        drag.exec_(Qt.MoveAction)
        self.setAcceptDrops(False)

QMimeData类可以设置很多数据,我们只需要使用setText即可,在我们重写的鼠标移动事件中,鼠标移动的时候将携带QMimeData对象。

按钮拖动移动

class MyPushButton2(QPushButton):

    def __init__(self, parent=None, text=''):
        super(MyPushButton2, self).__init__(parent)
        self.text = text
        self.setText(text)

    def mouseMoveEvent(self, e):
        if e.buttons() != Qt.LeftButton:
            return
        mimeData = QMimeData()
        mimeData.setText('move,' + self.text)
        drag = QDrag(self)
        drag.setMimeData(mimeData)
        drag.setHotSpot(e.pos() - self.rect().topLeft())
        drag.exec_(Qt.MoveAction)
        self.setAcceptDrops(False)

按钮2只是传递的字符信息不同了,这样可以方便我们进行后续处理

按钮可以拖动了(实际上是鼠标携带按钮信息),不代表我们已经可以放置按钮,QGroupBox默认不接受放置,所以我们又需要重新一个类

class MyGroupBox(QGroupBox):
    AddSignal = pyqtSignal(list)
    MoveSignal = pyqtSignal(list)

    def __init__(self, parent=None):
        super(MyGroupBox, self).__init__(parent)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, e):
        # print(e)
        if e.mimeData().hasText():
            e.accept()
        else:
            e.ignore()

    def dropEvent(self, e):
        data = e.mimeData().text().split(',')
        # print((e.pos().x(), e.pos().y()))
        if data[0] == 'add':
            self.AddSignal.emit([data[1], e.pos()])
        elif data[0] == 'move':
            self.MoveSignal.emit([data[1], e.pos()])

这次我们重写了两个方法,dragEnterEvent表示拖动移入事件,dropEvent表示放置事件,setAcceptDrops用来设置我们的类是否接收放置事件,默认是False。我们通过判断字符信息将按钮数据通过不同的信号发送给主窗口,主窗口再通过绑定不同函数执行相应的操作。

完整代码:

import sys
from PyQt5.QtCore import pyqtSignal, QMimeData, Qt
from PyQt5.QtGui import QDrag
from PyQt5.QtWidgets import QApplication, QGridLayout, QGroupBox, QWidget, QPushButton


class MyPushButton(QPushButton):

    def __init__(self, parent=None, text=''):
        super(MyPushButton, self).__init__(parent)
        self.text = text
        self.setText(text)

    def mouseMoveEvent(self, e):
        if e.buttons() != Qt.LeftButton:
            return
        mimeData = QMimeData()
        mimeData.setText('add,' + self.text)
        drag = QDrag(self)
        drag.setMimeData(mimeData)
        drag.exec_(Qt.MoveAction)
        self.setAcceptDrops(False)


class MyPushButton2(QPushButton):

    def __init__(self, parent=None, text=''):
        super(MyPushButton2, self).__init__(parent)
        self.text = text
        self.setText(text)

    def mouseMoveEvent(self, e):
        if e.buttons() != Qt.LeftButton:
            return
        mimeData = QMimeData()
        mimeData.setText('move,' + self.text)
        drag = QDrag(self)
        drag.setMimeData(mimeData)
        drag.setHotSpot(e.pos() - self.rect().topLeft())
        drag.exec_(Qt.MoveAction)
        self.setAcceptDrops(False)


class MyGroupBox(QGroupBox):
    AddSignal = pyqtSignal(list)
    MoveSignal = pyqtSignal(list)

    def __init__(self, parent=None):
        super(MyGroupBox, self).__init__(parent)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, e):
        # print(e)
        if e.mimeData().hasText():
            e.accept()
        else:
            e.ignore()

    def dropEvent(self, e):
        data = e.mimeData().text().split(',')
        # print((e.pos().x(), e.pos().y()))
        if data[0] == 'add':
            self.AddSignal.emit([data[1], e.pos()])
        elif data[0] == 'move':
            self.MoveSignal.emit([data[1], e.pos()])


class DragDemoView(QWidget):

    def __init__(self):
        super(DragDemoView, self).__init__()
        self.setUI()
        self.show()

    def setUI(self):
        self.setWindowTitle("DragDemoView")
        self.resize(QApplication.desktop().availableGeometry().width() - 400,
                    QApplication.desktop().availableGeometry().height() - 200)

        self.drawBox = MyGroupBox(self)
        self.drawBox.AddSignal.connect(self.add_button)
        self.drawBox.MoveSignal.connect(self.move_button)
        self.toolBox = QGroupBox(self)
        self.button1 = MyPushButton(self.toolBox, 'test')
        self.buttonDict = {}

        self.layout = QGridLayout(self)
        self.layout.addWidget(self.toolBox, 0, 0, 1, 1)
        self.layout.addWidget(self.drawBox, 0, 1, 1, 1)

    def add_button(self, data):
        n = 0
        buttonName = data[0] + str(n)
        while buttonName in self.buttonDict:
            n += 1
            buttonName = data[0] + str(n)

        button = MyPushButton2(self.drawBox, buttonName)
        self.buttonDict[buttonName] = button
        button.move(data[1])
        button.show()

    def move_button(self, data):
        button = self.buttonDict[data[0]]
        button.move(data[1])
        button.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = DragDemoView()
    app.exit(app.exec_())

主窗口决定了按钮的复制和移动,实际上就是通过按钮所传递的信息进行的操作,所有按钮信息必须唯一(上面的程序是通过判断按钮上的文字)。

如有疑问,可以评论联系我,谢谢。

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值