Search code examples
pythonuser-interfacepyqtpyqt5

How to Drag QLineEdit form one cell of QGridLayout to other cell in pyqt?


I have gridlayout with four cells (0,0),(0,1),(1,0),(1,1). Every cell is vertical layout with scrollbar. Initially only (0,0) cell contains QLineEdit in it. I want to drag and drop them in any one of the cells. How can I do it? I want to layout the cells like the image contained in the following link.

enter image description here

I have tried this code

main.py :

import sys

from PyQt5.QtWidgets import QApplication

from mywidgets import MyWidget

from myui import Ui_Form 



class MainWidget(MyWidget, Ui_Form):
    
    def __init__(self, *args, **kwargs):
        
        super().__init__()
        
        self.setupUi(self)
        
        self.show()
        
  
if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWidget()
    
    sys.exit(app.exec_())

mywidgets.py :

from PyQt5.QtWidgets import QLineEdit, QWidget, QScrollArea

from PyQt5.QtCore import Qt, QMimeData
from PyQt5.QtGui import QDrag, QPixmap

class MyLineEdit(QLineEdit):
    
    
    def mouseMoveEvent(self, e):

        if e.buttons() == Qt.LeftButton:
            drag = QDrag(self)
            mime = QMimeData()
            drag.setMimeData(mime)

            pixmap = QPixmap(self.size())
            self.render(pixmap)
            drag.setPixmap(pixmap)

            drag.exec_(Qt.MoveAction)
            
    
class MyWidget(QWidget):
    
    
    def dragEnterEvent(self, e):
        e.accept()
        
    def dropEvent(self, e):
        
        pos = e.pos()
        
        widget = e.source()
        
        print('accepted but not moved , there is no layout')
        print('pos : ', pos)
        print('event.source : ', widget , 'event.source.parent() :', widget.parent())
        
        widget.setParent(None)
        
        print('parent : ', self.parent())
        
        widget.show()
    
            
class MyScrollArea(QScrollArea):
    
    pass

my PyQt5-designer ui file translated with pyuic5 ;

myui.py :

from PyQt5 import QtCore, QtGui, QtWidgets

from PyQt5.QtCore import Qt, QMimeData
from PyQt5.QtGui import QDrag


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(698, 635)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
        Form.setSizePolicy(sizePolicy)
        Form.setAcceptDrops(True)
        self.gridLayout = QtWidgets.QGridLayout(Form)
        self.gridLayout.setObjectName("gridLayout")
        self.scrollArea = MyScrollArea(Form)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.scrollArea.sizePolicy().hasHeightForWidth())
        self.scrollArea.setSizePolicy(sizePolicy)
        self.scrollArea.setAcceptDrops(True)
        self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = MyWidget()
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, -219, 315, 561))
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents.sizePolicy().hasHeightForWidth())
        self.scrollAreaWidgetContents.setSizePolicy(sizePolicy)
        self.scrollAreaWidgetContents.setAcceptDrops(True)
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
        self.verticalLayout.setObjectName("verticalLayout")
        self.lineEdit_1 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_1.setObjectName("lineEdit_1")
        self.verticalLayout.addWidget(self.lineEdit_1)
        self.lineEdit_2 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.verticalLayout.addWidget(self.lineEdit_2)
        self.lineEdit_3 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.verticalLayout.addWidget(self.lineEdit_3)
        self.lineEdit_4 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_4.setObjectName("lineEdit_4")
        self.verticalLayout.addWidget(self.lineEdit_4)
        self.lineEdit_5 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_5.setObjectName("lineEdit_5")
        self.verticalLayout.addWidget(self.lineEdit_5)
        self.lineEdit_15 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_15.setObjectName("lineEdit_15")
        self.verticalLayout.addWidget(self.lineEdit_15)
        self.lineEdit_14 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_14.setObjectName("lineEdit_14")
        self.verticalLayout.addWidget(self.lineEdit_14)
        self.lineEdit_13 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_13.setObjectName("lineEdit_13")
        self.verticalLayout.addWidget(self.lineEdit_13)
        self.lineEdit_12 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_12.setObjectName("lineEdit_12")
        self.verticalLayout.addWidget(self.lineEdit_12)
        self.lineEdit_11 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_11.setObjectName("lineEdit_11")
        self.verticalLayout.addWidget(self.lineEdit_11)
        self.lineEdit_10 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_10.setObjectName("lineEdit_10")
        self.verticalLayout.addWidget(self.lineEdit_10)
        self.lineEdit_9 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_9.setObjectName("lineEdit_9")
        self.verticalLayout.addWidget(self.lineEdit_9)
        self.lineEdit_8 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_8.setObjectName("lineEdit_8")
        self.verticalLayout.addWidget(self.lineEdit_8)
        self.lineEdit_7 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_7.setObjectName("lineEdit_7")
        self.verticalLayout.addWidget(self.lineEdit_7)
        self.lineEdit_6 = MyLineEdit(self.scrollAreaWidgetContents)
        self.lineEdit_6.setObjectName("lineEdit_6")
        self.verticalLayout.addWidget(self.lineEdit_6)
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.gridLayout.addWidget(self.scrollArea, 0, 0, 1, 1)
        self.scrollArea_2 = MyScrollArea(Form)
        self.scrollArea_2.setAcceptDrops(True)
        self.scrollArea_2.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.scrollArea_2.setWidgetResizable(True)
        self.scrollArea_2.setObjectName("scrollArea_2")
        self.scrollAreaWidgetContents_2 = MyWidget()
        self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 315, 305))
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents_2.sizePolicy().hasHeightForWidth())
        self.scrollAreaWidgetContents_2.setSizePolicy(sizePolicy)
        self.scrollAreaWidgetContents_2.setAcceptDrops(True)
        self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2")
        self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2)
        self.gridLayout.addWidget(self.scrollArea_2, 0, 1, 1, 1)
        self.scrollArea_3 = MyScrollArea(Form)
        self.scrollArea_3.setAcceptDrops(True)
        self.scrollArea_3.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.scrollArea_3.setWidgetResizable(True)
        self.scrollArea_3.setObjectName("scrollArea_3")
        self.scrollAreaWidgetContents_3 = MyWidget()
        self.scrollAreaWidgetContents_3.setGeometry(QtCore.QRect(0, 0, 315, 304))
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents_3.sizePolicy().hasHeightForWidth())
        self.scrollAreaWidgetContents_3.setSizePolicy(sizePolicy)
        self.scrollAreaWidgetContents_3.setAcceptDrops(True)
        self.scrollAreaWidgetContents_3.setObjectName("scrollAreaWidgetContents_3")
        self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3)
        self.gridLayout.addWidget(self.scrollArea_3, 1, 0, 1, 1)
        self.scrollArea_4 = MyScrollArea(Form)
        self.scrollArea_4.setAcceptDrops(True)
        self.scrollArea_4.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.scrollArea_4.setWidgetResizable(True)
        self.scrollArea_4.setObjectName("scrollArea_4")
        self.scrollAreaWidgetContents_4 = MyWidget()
        self.scrollAreaWidgetContents_4.setGeometry(QtCore.QRect(0, 0, 315, 304))
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents_4.sizePolicy().hasHeightForWidth())
        self.scrollAreaWidgetContents_4.setSizePolicy(sizePolicy)
        self.scrollAreaWidgetContents_4.setAcceptDrops(True)
        self.scrollAreaWidgetContents_4.setObjectName("scrollAreaWidgetContents_4")
        self.scrollArea_4.setWidget(self.scrollAreaWidgetContents_4)
        self.gridLayout.addWidget(self.scrollArea_4, 1, 1, 1, 1)
        self.gridLayout.setColumnStretch(1, 1)
        self.gridLayout.setRowStretch(1, 1)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.lineEdit_1.setText(_translate("Form", "1"))
        self.lineEdit_2.setText(_translate("Form", "2"))
        self.lineEdit_3.setText(_translate("Form", "3"))
        self.lineEdit_4.setText(_translate("Form", "4"))
        self.lineEdit_5.setText(_translate("Form", "5"))
        self.lineEdit_15.setText(_translate("Form", "6"))
        self.lineEdit_14.setText(_translate("Form", "7"))
        self.lineEdit_13.setText(_translate("Form", "8"))
        self.lineEdit_12.setText(_translate("Form", "9"))
        self.lineEdit_11.setText(_translate("Form", "10"))
        self.lineEdit_10.setText(_translate("Form", "11"))
        self.lineEdit_9.setText(_translate("Form", "12"))
        self.lineEdit_8.setText(_translate("Form", "13"))
        self.lineEdit_7.setText(_translate("Form", "14"))
        self.lineEdit_6.setText(_translate("Form", "15"))


    
    def mouseMoveEvent(self, e):

        if e.buttons() == Qt.LeftButton:
            drag = QDrag(self)
            mime = QMimeData()
            drag.setMimeData(mime)
            drag.exec_(Qt.MoveAction)
            


from mywidgets import MyLineEdit, MyScrollArea, MyWidget

but it is not working:

enter image description here

output printed:

accepted but not moved , there is no layout
pos :  PyQt5.QtCore.QPoint(27, 95)
event.source :  <mywidgets.MyLineEdit object at ........> 
event.source.parent() : <mywidgets.MyWidget object at ........>
parent :  <PyQt5.QtWidgets.QWidget object at ......>

I want to drag elements from (0,0) cell and drop anyone of the cell such that it will remove from cell (0,0) and add in layout of cell where it dropped. Every cell contains a scrollbar because there can be many elements in each cell.

I guess is something related to layout and widget , not able in designer to add a layout without widgets in cell (0,1) ,(1.-,0) and (1,1) , and still have problem getting the layout out of a position in PyQt


Solution

  • OK kind of solved the layout problem thanks to an old post I used some time ago that went nearly forgotten answer to How to make QScrollArea working properly

    Alternatively, you can also do the same from Designer with a small workaround:

    add any widget (a button, a label, it doesn't matter) to the scrollAreaWidgetContents widget; you actually already have such a widget (the gridLayoutWidget_2 you created inside it), so you could use that for this purpose;

    right click on the scroll area and select grid layout from the "Lay out" sub menu;

    remove the widget added before (or the gridLayoutWidget_2 in your case);

    This is required because Designer doesn't allow to set a layout for a widget until it has at least one child widget.

    That explain how to create an empty layout in PyQt-Designer .

    My revised code ;

    main.py :

    import sys
    
    from PyQt5.QtWidgets import QApplication
    
    from mywidgets import MyWidget
    
    from myui import Ui_Form 
    
    
    
    class MainWidget(MyWidget, Ui_Form):
        
        def __init__(self, *args, **kwargs):
            
            super().__init__()
            
            self.setupUi(self)
            
            self.show()
            
      
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        w = MainWidget()
        
        sys.exit(app.exec_())
    

    mywidgets.py :

    from PyQt5.QtWidgets import QLineEdit, QWidget, QScrollArea
    
    from PyQt5.QtCore import Qt, QMimeData
    from PyQt5.QtGui import QDrag, QPixmap, QCursor
    
    
    class MyLineEdit(QLineEdit):
        
        
        def dragEnterEvent(self, e):
            
            e.ignore()
        
        
        def mouseMoveEvent(self, e):
    
            if e.buttons() == Qt.LeftButton:
                drag = QDrag(self)
                mime = QMimeData()
                drag.setMimeData(mime)
    
                pixmap = QPixmap(self.size())
                self.render(pixmap)
                drag.setPixmap(pixmap)
    
                drag.exec_(Qt.MoveAction)
                
        
    class MyWidget(QWidget):
        
        
        def dragEnterEvent(self, e):
            e.accept()
            
        def dropEvent(self, e):
            
            pos = e.pos()
            
            widget = e.source()
            
            print('accepted but not moved , there is no layout')
            print('pos : ', pos, 'mouse : ', QCursor.pos())
            print('event.source : ', widget , 'event.source.parent() :', widget.parent())
            
            widget.setParent(None)
            
            print('parent : ', self.parent() , self.parent().objectName())
            
            print('self.layput() : ', self.layout())
            
            print('self.objectName() : ', self.objectName())
            
            #widget.show() # not needed its shown in layout
            
            if self.layout() != None :
                
                self.layout().addWidget(e.source())
                
    class MyScrollArea(QScrollArea):
        
        pass
    

    my PyQt5-Designer ui file translated with pyuic5 ;

    myui.py :

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    from PyQt5.QtCore import Qt, QMimeData
    from PyQt5.QtGui import QDrag
    
    
    class Ui_Form(object):
        def setupUi(self, Form):
            Form.setObjectName("Form")
            Form.resize(698, 635)
            sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
            Form.setSizePolicy(sizePolicy)
            Form.setAcceptDrops(True)
            self.gridLayout = QtWidgets.QGridLayout(Form)
            self.gridLayout.setObjectName("gridLayout")
            self.scrollArea = MyScrollArea(Form)
            sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
            sizePolicy.setHorizontalStretch(1)
            sizePolicy.setVerticalStretch(1)
            sizePolicy.setHeightForWidth(self.scrollArea.sizePolicy().hasHeightForWidth())
            self.scrollArea.setSizePolicy(sizePolicy)
            self.scrollArea.setAcceptDrops(True)
            self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
            self.scrollArea.setWidgetResizable(True)
            self.scrollArea.setObjectName("scrollArea")
            self.scrollAreaWidgetContents = MyWidget()
            self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 315, 897))
            sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents.sizePolicy().hasHeightForWidth())
            self.scrollAreaWidgetContents.setSizePolicy(sizePolicy)
            self.scrollAreaWidgetContents.setAcceptDrops(True)
            self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
            self.verticalLayout = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
            self.verticalLayout.setSpacing(30)
            self.verticalLayout.setObjectName("verticalLayout")
            self.lineEdit_1 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_1.setObjectName("lineEdit_1")
            self.verticalLayout.addWidget(self.lineEdit_1)
            self.lineEdit_2 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_2.setObjectName("lineEdit_2")
            self.verticalLayout.addWidget(self.lineEdit_2)
            self.lineEdit_3 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_3.setObjectName("lineEdit_3")
            self.verticalLayout.addWidget(self.lineEdit_3)
            self.lineEdit_4 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_4.setObjectName("lineEdit_4")
            self.verticalLayout.addWidget(self.lineEdit_4)
            self.lineEdit_5 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_5.setObjectName("lineEdit_5")
            self.verticalLayout.addWidget(self.lineEdit_5)
            self.lineEdit_15 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_15.setObjectName("lineEdit_15")
            self.verticalLayout.addWidget(self.lineEdit_15)
            self.lineEdit_14 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_14.setObjectName("lineEdit_14")
            self.verticalLayout.addWidget(self.lineEdit_14)
            self.lineEdit_13 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_13.setObjectName("lineEdit_13")
            self.verticalLayout.addWidget(self.lineEdit_13)
            self.lineEdit_12 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_12.setObjectName("lineEdit_12")
            self.verticalLayout.addWidget(self.lineEdit_12)
            self.lineEdit_11 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_11.setObjectName("lineEdit_11")
            self.verticalLayout.addWidget(self.lineEdit_11)
            self.lineEdit_10 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_10.setObjectName("lineEdit_10")
            self.verticalLayout.addWidget(self.lineEdit_10)
            self.lineEdit_9 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_9.setObjectName("lineEdit_9")
            self.verticalLayout.addWidget(self.lineEdit_9)
            self.lineEdit_8 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_8.setObjectName("lineEdit_8")
            self.verticalLayout.addWidget(self.lineEdit_8)
            self.lineEdit_7 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_7.setObjectName("lineEdit_7")
            self.verticalLayout.addWidget(self.lineEdit_7)
            self.lineEdit_6 = MyLineEdit(self.scrollAreaWidgetContents)
            self.lineEdit_6.setObjectName("lineEdit_6")
            self.verticalLayout.addWidget(self.lineEdit_6)
            self.scrollArea.setWidget(self.scrollAreaWidgetContents)
            self.gridLayout.addWidget(self.scrollArea, 0, 0, 1, 1)
            self.scrollArea_2 = MyScrollArea(Form)
            self.scrollArea_2.setAcceptDrops(True)
            self.scrollArea_2.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
            self.scrollArea_2.setWidgetResizable(True)
            self.scrollArea_2.setObjectName("scrollArea_2")
            self.scrollAreaWidgetContents_2 = MyWidget()
            self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 315, 305))
            sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents_2.sizePolicy().hasHeightForWidth())
            self.scrollAreaWidgetContents_2.setSizePolicy(sizePolicy)
            self.scrollAreaWidgetContents_2.setAcceptDrops(True)
            self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2")
            self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents_2)
            self.verticalLayout_3.setObjectName("verticalLayout_3")
            self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2)
            self.gridLayout.addWidget(self.scrollArea_2, 0, 1, 1, 1)
            self.scrollArea_3 = MyScrollArea(Form)
            self.scrollArea_3.setAcceptDrops(True)
            self.scrollArea_3.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
            self.scrollArea_3.setWidgetResizable(True)
            self.scrollArea_3.setObjectName("scrollArea_3")
            self.scrollAreaWidgetContents_3 = MyWidget()
            self.scrollAreaWidgetContents_3.setGeometry(QtCore.QRect(0, 0, 315, 304))
            sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents_3.sizePolicy().hasHeightForWidth())
            self.scrollAreaWidgetContents_3.setSizePolicy(sizePolicy)
            self.scrollAreaWidgetContents_3.setAcceptDrops(True)
            self.scrollAreaWidgetContents_3.setObjectName("scrollAreaWidgetContents_3")
            self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents_3)
            self.verticalLayout_2.setObjectName("verticalLayout_2")
            self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3)
            self.gridLayout.addWidget(self.scrollArea_3, 1, 0, 1, 1)
            self.scrollArea_4 = MyScrollArea(Form)
            self.scrollArea_4.setAcceptDrops(True)
            self.scrollArea_4.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
            self.scrollArea_4.setWidgetResizable(True)
            self.scrollArea_4.setObjectName("scrollArea_4")
            self.scrollAreaWidgetContents_4 = MyWidget()
            self.scrollAreaWidgetContents_4.setGeometry(QtCore.QRect(0, 0, 315, 304))
            sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents_4.sizePolicy().hasHeightForWidth())
            self.scrollAreaWidgetContents_4.setSizePolicy(sizePolicy)
            self.scrollAreaWidgetContents_4.setAcceptDrops(True)
            self.scrollAreaWidgetContents_4.setObjectName("scrollAreaWidgetContents_4")
            self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents_4)
            self.verticalLayout_4.setObjectName("verticalLayout_4")
            self.scrollArea_4.setWidget(self.scrollAreaWidgetContents_4)
            self.gridLayout.addWidget(self.scrollArea_4, 1, 1, 1, 1)
            self.gridLayout.setColumnStretch(1, 1)
            self.gridLayout.setRowStretch(1, 1)
    
            self.retranslateUi(Form)
            QtCore.QMetaObject.connectSlotsByName(Form)
    
        def retranslateUi(self, Form):
            _translate = QtCore.QCoreApplication.translate
            Form.setWindowTitle(_translate("Form", "Form"))
            self.lineEdit_1.setText(_translate("Form", "1"))
            self.lineEdit_2.setText(_translate("Form", "2"))
            self.lineEdit_3.setText(_translate("Form", "3"))
            self.lineEdit_4.setText(_translate("Form", "4"))
            self.lineEdit_5.setText(_translate("Form", "5"))
            self.lineEdit_15.setText(_translate("Form", "6"))
            self.lineEdit_14.setText(_translate("Form", "7"))
            self.lineEdit_13.setText(_translate("Form", "8"))
            self.lineEdit_12.setText(_translate("Form", "9"))
            self.lineEdit_11.setText(_translate("Form", "10"))
            self.lineEdit_10.setText(_translate("Form", "11"))
            self.lineEdit_9.setText(_translate("Form", "12"))
            self.lineEdit_8.setText(_translate("Form", "13"))
            self.lineEdit_7.setText(_translate("Form", "14"))
            self.lineEdit_6.setText(_translate("Form", "15"))
    
        def mouseMoveEvent(self, e):
    
            if e.buttons() == Qt.LeftButton:
                drag = QDrag(self)
                mime = QMimeData()
                drag.setMimeData(mime)
                drag.exec_(Qt.MoveAction)
                
    
    
    from mywidgets import MyLineEdit, MyScrollArea, MyWidget
    
    

    Picture of results:

    enter image description here

    Only big problem with this setup is that when QLineEdit-Widgets

    get dragged and dropped around they are added to the layout at the end of it,

    don't know how to insert them in the exact position where they are dropped, to me is not an easy problem to solve