class ChangeMethodsDnDTagList(QtWidgets.QPlainTextEdit):
def __init__(self, obj):
super().__init__()
self.obj = obj # will be type = BeforeQtWidgets.QPlainTextEdit
self.obj.dragEnterEvent = self.dragEnterEvent
self.obj.dropEvent = self.dropEvent
def dragEnterEvent(self, event):
if event.mimeData().hasText():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if check_text(event.mimeData().text()):
if self.obj is not None:
if self.obj.toPlainText() != '':
self.obj.setPlainText(self.obj.toPlainText() + ', ' + event.mimeData().text())
else:
self.obj.setPlainText(event.mimeData().text())
class Application(QtWidgets.QMainWindow, design.Ui_MainWindow, QtWidgets.QWidget, QtCore.QEvent):
def __init__(self):
...
super().__init__()
...
self.setupUi(self)
...
ChangeMethodsDnDTagList(self.in_tags_list)
Drag and Drop works well but after that, the cursor freezes and does not update (blinking, change position).
The minimal reproducible example: testform.py:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'testform.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(502, 271)
MainWindow.setMinimumSize(QtCore.QSize(502, 271))
MainWindow.setMaximumSize(QtCore.QSize(502, 271))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.in_tags_list = QtWidgets.QPlainTextEdit(self.centralwidget)
self.in_tags_list.setGeometry(QtCore.QRect(5, 5, 481, 201))
self.in_tags_list.setInputMethodHints(QtCore.Qt.ImhLatinOnly|QtCore.Qt.ImhMultiLine)
self.in_tags_list.setPlainText("")
self.in_tags_list.setObjectName("in_tags_list")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
test.py:
import sys
from PyQt5 import QtWidgets
from PyQt5 import QtCore
import testform as design
import re
class Application(QtWidgets.QMainWindow, design.Ui_MainWindow, QtWidgets.QWidget, QtCore.QEvent):
def __init__(self):
super().__init__()
self.setupUi(self)
self.setCentralWidget(self.centralwidget)
ChangeMethodsDnDTagList(self.in_tags_list)
class ChangeMethodsDnDTagList(QtWidgets.QPlainTextEdit):
def __init__(self, obj):
super().__init__()
self.obj = obj # will be type = BeforeQtWidgets.QPlainTextEdit
self.obj.dragEnterEvent = self.dragEnterEvent
self.obj.dropEvent = self.dropEvent
def dragEnterEvent(self, event):
if event.mimeData().hasText():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if check_text(event.mimeData().text()):
if self.obj is not None:
if self.obj.toPlainText() != '':
self.obj.setPlainText(self.obj.toPlainText() + ', ' + event.mimeData().text())
else:
self.obj.setPlainText(event.mimeData().text())
def check_text(text, mask="""^[a-zA-Z0-9_:, \n\t]+$"""):
"""Check input text"""
match = re.match(mask, text)
return bool(match)
def main():
app = QtWidgets.QApplication(sys.argv)
window = Application()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You need to reimplement dragMoveEvent
too, it can be identical to dragEnterEvent
so just add one line similar to the others:
class ChangeMethodsDnDTagList(QtWidgets.QPlainTextEdit):
def __init__(self, obj):
super().__init__()
self.obj = obj # will be type = BeforeQtWidgets.QPlainTextEdit
self.obj.dragEnterEvent = self.dragEnterEvent
self.obj.dropEvent = self.dropEvent
self.obj.dragMoveEvent = self.dragEnterEvent
Then include a line in dropEvent
to move the cursor to the end of the document after the drop.
def dropEvent(self, event):
if check_text(event.mimeData().text()):
if self.obj is not None:
if self.obj.toPlainText() != '':
self.obj.setPlainText(self.obj.toPlainText() + ', ' + event.mimeData().text())
else:
self.obj.setPlainText(event.mimeData().text())
self.obj.moveCursor(QtGui.QTextCursor.End)