.setDragEnabled(True) ให้สามารถลากได้import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit,QVBoxLayout
class Natang(QWidget):
    def __init__(self):
        super().__init__()
        self.setStyleSheet('font-family: Tahoma')
        self.vbl = QVBoxLayout()
        self.setLayout(self.vbl)
        # ช่องบน ทำให้ลากได้
        self.chongkhian1 = QLineEdit('ลองคลุมแล้วลากไปปล่อยดู')
        self.vbl.addWidget(self.chongkhian1)
        self.chongkhian1.setDragEnabled(True) # ทำให้ลากเอาข้อมูลได้
        # ช่องล่าง ไม่ได้ตั้งให้ลากได้
        self.chongkhian2 = QLineEdit('')
        self.vbl.addWidget(self.chongkhian2)
        self.show()
qAp = QApplication(sys.argv)
natang = Natang()
qAp.exec_()

import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit,QVBoxLayout
class Chongkhian(QLineEdit):
    def __init__(self,*arg,**kwarg):
        super().__init__(*arg,**kwarg)
        self.setDragEnabled(True) # ทำให้สามารถลากได้
    def dragMoveEvent(self,e): # เมื่อมีการเคลื่อนเมาส์ขณะกดลากอยู่
        if(e.source()!=self): # หากพื้นที่ที่ลากนั้นไม่ได้อยู่ในที่เดียวกับแหล่งของข้อมูลที่ลาก
            QLineEdit.dragMoveEvent(self,e) # ให้ทำคำสั่งที่ปกติควรทำเวลาลากเมาส์ไปภายในกล่อง
    def dragEnterEvent(self,e):
        e.accept() # เมื่อลากข้อมูลเข้ามาให้ยอมรับ
    def dropEvent(self,e): # เมื่อลากมาวางในอีกกล่อง
        e.source().del_() # ลบข้อความในกล่องเดิมส่วนที่คลุมแล้วลากมา
        self.insert(e.mimeData().text()) # นำข้อความที่ลบจากกล่องเดิมมาเติมให้กล่องที่ลากไป
class Natang(QWidget):
    def __init__(self):
        super().__init__()
        self.setStyleSheet('font-family: Courier New; font-size: 18px')
        self.vbl = QVBoxLayout()
        self.setLayout(self.vbl)
        # สร้างช่องเขียนข้อความโดยใช้คลาสใหม่ที่สร้างขึ้นมา
        self.chongkhian1 = Chongkhian('กล่องหนึ่ง')
        self.vbl.addWidget(self.chongkhian1)
        self.chongkhian2 = Chongkhian('กล่องสอง')
        self.vbl.addWidget(self.chongkhian2)
        self.show()
qAp = QApplication(sys.argv)
natang = Natang()
qAp.exec_()

import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLabel,QHBoxLayout,QVBoxLayout,QFrame
from PyQt5.QtCore import Qt,QMimeData
from PyQt5.QtGui import QDrag
class Maephim(QLabel): # ส่วนข้อความที่จะเป็นแม่พิมพ์ คือให้ลากตัวหนังสือจากตรงนี้ไปวางที่อื่นได้
    def __init__(self,*arg,**kwarg):
        super().__init__(*arg,**kwarg)
        self.setStyleSheet('color: #b24; font-size: 60px;')
        self.setFrameShape(QFrame.Box)
        self.setAlignment(Qt.AlignCenter)
        self.setFixedSize(50,50)
    def mousePressEvent(self,e): # เมื่อกดเมาส์ที่ widget นั้น
        mida = QMimeData() # ก็เริ่มสร้างออบเจ็กต์เก็บ mime data ขึ้นมา
        mida.setText(self.text()) # แล้วเอาข้อความตัวหนังสือยัดใส่ให้เป็น mime data ในนั้น
        drag = QDrag(self) # สร้างออบเจ็กต์แทน event ของการลาก
        drag.setMimeData(mida) # นำข้อมูล mimedata ยัดใส่เข้าไป
        drag.exec_() # สั่ง exec_ เพื่อให้เริ่ม event การลากขึ้น
class Kradan(QFrame): # กระดานที่จะเอาข้อมูลที่ลากจากแม่พิมพ์เข้ามาวาง
    def __init__(self):
        super().__init__()
        self.setFixedSize(400,300)
        self.setStyleSheet('background-color: #6a4;')
        self.setFrameShape(QFrame.Panel)
        self.setFrameShadow(QFrame.Raised)
        self.setLineWidth(5)
        self.setAcceptDrops(True) # ตั้งให้รับข้อมูลที่ลากเข้าได้
    def dragEnterEvent(self,e):
        if(type(e.source())==Maephim): # ให้รับเฉพาะเมื่อเป็นข้อมูลที่ลากมาจากออบเจ็กต์แม่พิมพ์เท่านั้น
            e.accept()
    def dropEvent(self,e): # เมื่อปล่อยเมาส์หลังลากตัวหนังสือมาวาง
        label = QLabel(e.mimeData().text(),self) # สร้าง QLabel แล้วนำตัวหนังสือจาก mime data มาใส่
        label.setStyleSheet('background-color: None; color: #fff; font-size: 24px;')
        label.resize(40,50)
        label.setAlignment(Qt.AlignCenter)
        label.move(e.pos().x()-20,e.pos().y()-25)
        label.show()
class Natang(QWidget):
    def __init__(self):
        super().__init__()
        self.setStyleSheet('font-family: Tahoma;')
        hbl = QHBoxLayout()
        self.setLayout(hbl)
        vbl = QVBoxLayout()
        hbl.addLayout(vbl)
        for s in ['ก','ข','ค','ง','จ']: # วางตัวอักษรที่เป็นแม่พิมพ์ไว้ทางซ้าย
            vbl.addWidget(Maephim(s))
        hbl.addWidget(Kradan()) # วางกระดานไว้ทางขวา
        self.show()
qAp = QApplication(sys.argv)
natang = Natang()
qAp.exec_()


import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLabel
from PyQt5.QtCore import Qt,QMimeData
from PyQt5.QtGui import QDrag,QPixmap
# สร้างคลาสของ widget ใส่รูปที่ลากเคลื่อนได้
class Rupkhlueandai(QLabel):
    def mousePressEvent(self,e): # เมื่อเมาส์ถูกกด
        if(e.button()==Qt.LeftButton): # ถ้าที่คลิกนั้นเป็นปุ่มเมาส์ซ้าย
            self.xykot = e.pos() # บันทึกตำแหน่งที่ถูกคลิกไว้
            drag = QDrag(self) # สร้างออบเจ็กต์ของ event การลาก
            drag.setMimeData(QMimeData()) # ใส่ mime data ลงไป
            drag.setPixmap(QPixmap('qbicon.png').scaledToWidth(25)) # ใส่รูปที่ให้แสดงเวลาที่ลาก
            drag.exec_() # เริ่ม event การลาก
class Natang(QWidget):
    def __init__(self):
        super().__init__()
        self.setFixedSize(450,350)
        self.setStyleSheet('font-family: Tahoma;')
        self.setAcceptDrops(True) # ตั้งให้หน้าต่างนี้รับการลากได้
        self.rup = Rupkhlueandai('',self) # สร้างตัวรูปเลื่อนที่เลื่อนได้ขึ้นมา
        self.rup.setPixmap(QPixmap('qbicon.png')) # ใส่รูป
        self.rup.setGeometry(50,50,100,100)
        self.show()
    def dragEnterEvent(self,e):
        if(e.source()==self.rup): # ให้ยอมรับการลากเฉพาะเมื่อเป็นตัวออบเจ็กต์รูปที่เราสร้างขึ้นเองนั้น
            e.accept()
    def dropEvent(self,e):
        so = e.source() # ออบเจ็กต์ตัวรูป
        so.move(e.pos()-so.xykot) # ย้ายไปยังตำแหน่งที่วางเมาส์
qAp = QApplication(sys.argv)
natang = Natang()
qAp.exec_()

import sys
from PyQt5.QtWidgets import QApplication,QWidget,QHBoxLayout,QListWidget
from PyQt5.QtGui import QDrag
from PyQt5.QtCore import QMimeData
# เขียนคลาสของ QListWidget ใหม่ให้สามารถลากข้อความไปมาได้
class Chongraikan(QListWidget):
    def __init__(self,*arg,**kwarg):
        super().__init__(*arg,**kwarg)
        self.setStyleSheet('font-family: Courier New; font-size: 29px; background-color: #fdd; color: #056;')
        self.setAcceptDrops(True) # ตั้งให้รับการลากเข้าได้
    def mouseMoveEvent(self,e):
        mida = QMimeData() # สร้าง mime data ขึ้นมา
        mida.setText(self.currentItem().text()) #นำข้อความจากตัวที่เลือกอยู่ใส่เข้าไป
        drag = QDrag(self) # สร้าง event การลาก
        drag.setMimeData(mida) # ใส่ mime data ให้
        drag.exec_() # เริ่ม event การลาก
    def dragMoveEvent(self,e):
        if(e.source()==self):
            QListWidget.dragMoveEvent(self,e)
    def dragEnterEvent(self,e):
        e.accept()
    def dropEvent(self,e):
        mida = e.mimeData()
        so = e.source() # ตัวพื้นที่แสดงกลุ่มข้อความที่เป็นที่มาของข้อความที่ลากมา
        so.takeItem(so.row(so.currentItem())) # ลบข้อความตัวนั้นออกจากที่เดิม
        self.addItem(mida.text()) # ใส่ข้อความลงไปให้พื้นที่ส่วนที่ถูกปล่อยเมาส์
class Natang(QWidget):
    def __init__(self):
        super().__init__()
        self.hbl = QHBoxLayout()
        self.setLayout(self.hbl)
        # สร้างพื้นที่แสดงกลุ่มข้อความด้านซ้าย
        self.chongraikan1 = Chongraikan()
        self.hbl.addWidget(self.chongraikan1)
        self.chongraikan1.setFixedSize(200,300)
        self.chongraikan1.addItems(['ส้ม','ละมุด','ลำไย','กล้วย']) # ป้อนข้อความเริ่มต้น
        # สร้างพื้นที่แสดงกลุ่มข้อความด้านขวา
        self.chongraikan2 = Chongraikan()
        self.hbl.addWidget(self.chongraikan2)
        self.chongraikan2.setFixedSize(200,300)
        self.chongraikan2.addItems(['องุ่น','เงาะ','ลิ้นจี่','มะม่วง','แตงโม'])
        
        self.show()
qAp = QApplication(sys.argv)
natang = Natang()
qAp.exec_()

ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ