Как перетащить QLineEdit из одной ячейки QGridLayout в другую ячейку в pyqt?

У меня есть сетка с четырьмя ячейками (0,0), (0,1), (1,0), (1,1). Каждая ячейка имеет вертикальную компоновку с полосой прокрутки. Изначально только ячейка (0,0) содержит QLineEdit. Я хочу перетащить их в любую из ячеек. Как мне это сделать? Я хочу расположить ячейки так, как показано на следующей ссылке .

Я попробовал этот код

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

мой файл PyQt5-дизайнера ui, переведенный с помощью 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

Но это не работает:

вывод напечатан:

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 ......>

Я хочу перетащить элементы из ячейки (0,0) и удалить любую из ячеек так, чтобы она была удалена из ячейки (0,0) и добавлена ​​в макет ячейки, в которую он был перемещен. Каждая ячейка содержит полосу прокрутки, поскольку в каждой ячейке может быть много элементов.

Я предполагаю, что это что-то связано с макетом и виджетом, в дизайнере невозможно добавить макет без виджетов в ячейку (0,1), (1.-,0) и (1,1), и все еще возникают проблемы с выводом макета. позиции в PyQt

Предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.

Community 23.04.2024 14:43

Не говорите нам, что то, что вы пробовали, не работает: покажите нам, что вы пробовали. Пожалуйста, не торопитесь, чтобы предоставить правильный минимальный воспроизводимый пример (и, пожалуйста, прочитайте эту ссылку, нам нужен не полный код, а минимальный код, который позволит нам воспроизвести проблему), а затем отредактируйте свой опубликуйте и включите его, объяснив, что происходит, когда вы его запускаете, и любые проблемы, связанные с его поведением.

musicamante 23.04.2024 21:21

изображение, на которое вы ссылаетесь, не является результатом связанного с вами кода

pippo1980 24.04.2024 00:24

Привет @musicmante, я отредактировал код, который использую. Пожалуйста, дайте мне какое-нибудь решение. Я новичок, поэтому впервые создаю функцию перетаскивания в Pyqt.

Kskrishna 24.04.2024 06:08

@musicamante попытался получить минимальный код для вопроса Кскришны, надеюсь, это имеет какой-то смысл

pippo1980 28.04.2024 19:31
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
5
98
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Хорошо, проблема с макетом решена благодаря старому посту, который я использовал некоторое время назад и который почти забылся ответ на вопрос «Как заставить QScrollArea работать правильно»

Альтернативно, вы также можете сделать то же самое в Designer, воспользовавшись небольшим обходным решением:

добавить любой виджет (кнопку, метку, не важно) в виджет ScrollAreaWidgetContents; на самом деле у вас уже есть такой виджет (gridLayoutWidget_2, который вы создали внутри него), поэтому вы можете использовать его для этой цели;

щелкните правой кнопкой мыши область прокрутки и выберите макет сетки в подменю «Макет»;

удалите добавленный ранее виджет (или GridLayoutWidget_2 в вашем случае);

Это необходимо, поскольку Designer не позволяет устанавливать макет виджета, пока у него не будет хотя бы одного дочернего виджета.

Это объясняет, как создать пустой макет в PyQt-Designer.

Мой исправленный код;

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

мой файл пользовательского интерфейса PyQt5-Designer, переведенный с помощью 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

Изображение результатов:

Единственная большая проблема с этой настройкой заключается в том, что когда QLineEdit-Виджеты

перетаскиваются и добавляются в макет в конце,

не знаю, как вставить их именно в то место, куда они упали, для меня это непростая проблема

спасибо @pippo, это действительно помогло и решило мою проблему.

Kskrishna 06.05.2024 13:43

ОК, пошли немного дальше:

Мой исправленный код;

main.py :

import sys

from PyQt5.QtWidgets import QApplication, QWidget

from myui_bis import Ui_Form 


class MainWidget(QWidget, Ui_Form):
    
    def __init__(self, *args, **kwargs):
        
        super().__init__()
        
        self.setupUi(self)
        
        self.pushButton.clicked.connect(self.printAcceptDrops)
        
        self.show()
        
    def printAcceptDrops(self):
        
        print('printAcceptDrops : ')

        print('Mainwidget : ', self.acceptDrops())

        print('self.scrollAreaWidgetContents : ', self.scrollAreaWidgetContents.acceptDrops())       
        print('self.scrollAreaWidgetContents_2 : ', self.scrollAreaWidgetContents_2.acceptDrops())   
        print('self.scrollAreaWidgetContents_3 : ', self.scrollAreaWidgetContents_3.acceptDrops())   
        print('self.scrollAreaWidgetContents_4 : ', self.scrollAreaWidgetContents_4.acceptDrops()) 
        
        

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWidget()
    
    sys.exit(app.exec_())

мой mywidgets.py:

from PyQt5.QtWidgets import QLineEdit, QWidget, QScrollArea, QScroller

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

from PyQt5 import QtGui

from PyQt5 import QtCore

from PyQt5 import QtWidgets

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

        print('ENTER DRAG EVENT IN ', self.objectName())
        
        e.accept()
        
        
    def dropEvent(self, e):
        
        widget = e.source()
        
        print('\n dropped on widget !!!!!!!!!!!!\n\n')
        
        
        if widget == self :
            
            return
        
        if widget.parent().layout().count() == 1:
            
            print('=============== 1   qlineedit')
            
            widget.parent().layout().parent().setAcceptDrops(True)
        
       
        widget.setParent(None)
        
self.parent().layout().insertWidget(self.parent().layout().indexOf(self) , widget)
       
    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):
        
        print('ENTER DRAG EVENT IN ', self.objectName())
        
        print('self.layout.count()', self.layout().count())
        
        e.accept()
        
    def dropEvent(self, e):
        
        pos = e.pos()
        
        widget = e.source()
        
        print('pos : ', pos, 'mouse : ', QCursor.pos())
        print('event.source : ', widget , 'event.source.parent() :', widget.parent())
        
        print('event.source  name: ', widget.objectName()) 
        
        print('parent : ', self.parent() , self.parent().objectName())
        
        print('self.layput() : ', self.layout())
        
        print('self.objectName() : ', self.objectName())
        
        if widget.parent().layout().count() == 1:
            
            print('=============== 1   WIDGET')
            
            widget.parent().layout().parent().setAcceptDrops(True)

        if self.layout().count() == 0 :
            
            widget.setParent(None)
            
            self.layout().addWidget(widget)
            
            self.setAcceptDrops(False)
            
        
class MyScrollArea(QScrollArea):
    
    def __init__(self , parent = None):
        super(MyScrollArea, self).__init__(parent)
           

мой файл пользовательского интерфейса PyQt5-Designer, переведенный с помощью pyuic5 myui_bis:

from PyQt5 import QtCore, 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, 672)
        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(False)
        self.gridLayout = QtWidgets.QGridLayout(Form)
        self.gridLayout.setObjectName("gridLayout")
        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, 303))
        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.setSpacing(30)
        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, 303))
        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.setSpacing(30)
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.scrollArea_4.setWidget(self.scrollAreaWidgetContents_4)
        self.gridLayout.addWidget(self.scrollArea_4, 1, 1, 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, 304))
        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.setSpacing(30)
        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 = 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, -304, 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(False)
        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.pushButton = QtWidgets.QPushButton(Form)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
        self.pushButton.setSizePolicy(sizePolicy)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 2, 0, 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"))
        self.pushButton.setText(_translate("Form", "Check AcceptDrops"))

from mywidgets import MyLineEdit, MyScrollArea, MyWidget

Теперь виджеты QLineEdit добавляются в макеты ScrollAreas, когда они пусты, но тогда для их атрибута AcceptDrops установлено значение False, и следующие виджеты QLineEdit необходимо переместить на уже существующие, занимая их позиции индекса макета внутри макетов. Если в макете не осталось виджетов, для значения AcceptDrops снова устанавливается значение True.

Единственная большая проблема сейчас заключается в том, что я не могу одновременно прокручивать и перетаскивать ни в одной из четырех областей прокрутки, но этот сбой присутствовал и в предыдущем ответе.

Нажав кнопку Check AcceptDrops QPushButton, вы получите значения виджетов acceptDrops():

printAcceptDrops : 
Mainwidget :  False
self.scrollAreaWidgetContents :  False
self.scrollAreaWidgetContents_2 :  False
self.scrollAreaWidgetContents_3 :  True
self.scrollAreaWidgetContents_4 :  True

Другие вопросы по теме