PyQt5 QTextEdit自动补全
PyQt5 QTextEdit auto completion
正在寻找一种使用 QTextEdit 和 QCompleter 进行自动完成的方法。我读过这是可能的,但没有找到任何例子......
我正在使用 python3.4 和 PyQt5
我正在寻找一个非常基本的示例
感谢您的帮助
这里有一个例子……我已经研究过了……尽管它在 python3.3 和 pyqt4 中。我想它应该不会有太大的不同..
你将不得不改变从PyQt4到从PyQt5
快捷键是 Ctrl+Space 显示建议和 Ctrl+ E 自动完成第一个可行的建议
mMyTextEdit.py
from PyQt4 import QtGui,QtCore
from mMyDictionaryCompleter import MyDictionaryCompleter
#===============================================================================
# MyTextEdit
#===============================================================================
class MyTextEdit(QtGui.QTextEdit):
#|-----------------------------------------------------------------------------|
# class Variables
#|-----------------------------------------------------------------------------|
#no classVariables
# myFocusOutSignal=QtCore.pyqtSignal(str)
#|-----------------------------------------------------------------------------|
# Constructor
#|-----------------------------------------------------------------------------|
def __init__(self,*args):
#*args to set parent
QtGui.QLineEdit.__init__(self,*args)
font=QtGui.QFont()
font.setPointSize(12)
self.setFont(font)
self.completer = None
#|--------------------------End of __init__------------------------------------|
#|-----------------------------------------------------------------------------|
# setCompleter
#|-----------------------------------------------------------------------------|
def setCompleter(self, completer):
if self.completer:
self.disconnect(self.completer, 0, self, 0)
if not completer:
return
completer.setWidget(self)
completer.setCompletionMode(QtGui.QCompleter.PopupCompletion)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.completer = completer
# self.connect(self.completer,
# QtCore.SIGNAL("activated(const QString&)"), self.insertCompletion)
self.completer.insertText.connect(self.insertCompletion)
#|-----------------------End of setCompleter-------------------------------------|
#|-----------------------------------------------------------------------------|
# insertCompletion
#|-----------------------------------------------------------------------------|
def insertCompletion(self, completion):
tc = self.textCursor()
extra = (len(completion) -
len(self.completer.completionPrefix()))
tc.movePosition(QtGui.QTextCursor.Left)
tc.movePosition(QtGui.QTextCursor.EndOfWord)
tc.insertText(completion[-extra:])
self.setTextCursor(tc)
#|-----------------------End of insertCompletion-------------------------------|
#|-----------------------------------------------------------------------------|
# textUnderCursor
#|-----------------------------------------------------------------------------|
def textUnderCursor(self):
tc = self.textCursor()
tc.select(QtGui.QTextCursor.WordUnderCursor)
return tc.selectedText()
#|-----------------------End of textUnderCursor--------------------------------|
#|-----------------------------------------------------------------------------|
# focusInEvent
#|-----------------------------------------------------------------------------|
#---override
def focusInEvent(self, event):
if self.completer:
self.completer.setWidget(self);
QtGui.QTextEdit.focusInEvent(self, event)
#|-----------------------End of focusInEvent-------------------------------------|
#|-----------------------------------------------------------------------------|
# keyPressEvent
#|-----------------------------------------------------------------------------|
#---override
def keyPressEvent(self, event):
if self.completer and self.completer.popup() and self.completer.popup().isVisible():
if event.key() in (
QtCore.Qt.Key_Enter,
QtCore.Qt.Key_Return,
QtCore.Qt.Key_Escape,
QtCore.Qt.Key_Tab,
QtCore.Qt.Key_Backtab):
event.ignore()
return
## has ctrl-Space been pressed??
isShortcut = (event.modifiers() == QtCore.Qt.ControlModifier and\
event.key() == QtCore.Qt.Key_Space)
## modifier to complete suggestion inline ctrl-e
inline = (event.modifiers() == QtCore.Qt.ControlModifier and \
event.key() == QtCore.Qt.Key_E)
## if inline completion has been chosen
if inline:
# set completion mode as inline
self.completer.setCompletionMode(QtGui.QCompleter.InlineCompletion)
completionPrefix = self.textUnderCursor()
if (completionPrefix != self.completer.completionPrefix()):
self.completer.setCompletionPrefix(completionPrefix)
self.completer.complete()
# self.completer.setCurrentRow(0)
# self.completer.activated.emit(self.completer.currentCompletion())
# set the current suggestion in the text box
self.completer.insertText.emit(self.completer.currentCompletion())
# reset the completion mode
self.completer.setCompletionMode(QtGui.QCompleter.PopupCompletion)
return
if (not self.completer or not isShortcut):
pass
QtGui.QTextEdit.keyPressEvent(self, event)
# debug
# print("After controlspace")
# print("isShortcut is: {}".format(isShortcut))
# debug over
## ctrl or shift key on it's own??
ctrlOrShift = event.modifiers() in (QtCore.Qt.ControlModifier ,\
QtCore.Qt.ShiftModifier)
if ctrlOrShift and event.text()== '':
# ctrl or shift key on it's own
return
# debug
# print("After on its own")
# print("isShortcut is: {}".format(isShortcut))
# debug over
# eow = QtCore.QString("~!@#$%^&*()_+{}|:\"<>?,./;'[]\-=") #end of word
# eow = "~!@#$%^&*()_+{}|:\"<>?,./;'[]\-=" #end of word
eow = "~!@#$%^&*+{}|:\"<>?,./;'[]\-=" #end of word
hasModifier = ((event.modifiers() != QtCore.Qt.NoModifier) and\
not ctrlOrShift)
completionPrefix = self.textUnderCursor()
# print('event . text = {}'.format(event.text().right(1)))
# if (not isShortcut and (hasModifier or event.text()=='' or\
# len(completionPrefix) < 3 or \
# eow.contains(event.text().right(1)))):
if not isShortcut :
if self.completer.popup():
self.completer.popup().hide()
return
# print("complPref: {}".format(completionPrefix))
# print("completer.complPref: {}".format(self.completer.completionPrefix()))
# print("mode: {}".format(self.completer.completionMode()))
# if (completionPrefix != self.completer.completionPrefix()):
self.completer.setCompletionPrefix(completionPrefix)
popup = self.completer.popup()
popup.setCurrentIndex(
self.completer.completionModel().index(0,0))
cr = self.cursorRect()
cr.setWidth(self.completer.popup().sizeHintForColumn(0)
+ self.completer.popup().verticalScrollBar().sizeHint().width())
self.completer.complete(cr) ## popup it up!
#|-----------------------End of keyPressEvent----------------------------------|
if __name__ == "__main__":
app = QtGui.QApplication([])
completer = MyDictionaryCompleter()
te = MyTextEdit()
te.setCompleter(completer)
te.show()
app.exec_()
mMyDictionaryCompleter.py
#===============================================================================
# MyDictionaryCompleter
#===============================================================================
from PyQt4 import QtGui, QtCore
class MyDictionaryCompleter(QtGui.QCompleter):
#|-----------------------------------------------------------------------------|
# class Variables
#|-----------------------------------------------------------------------------|
insertText = QtCore.pyqtSignal(str)
#no classVariables
#|-----------------------------------------------------------------------------|
# Constructor
#|-----------------------------------------------------------------------------|
def __init__(self, myKeywords=None,parent=None):
myKeywords =['apple','aggresive','ball','bat','cat','cycle','dog','dumb',\
'elephant','engineer','food','file','good','great',\
'hippopotamus','hyper','india','ireland','just','just',\
'key','kid','lemon','lead','mute','magic',\
'news','newyork','orange','oval','parrot','patriot',\
'question','queue','right','rest','smile','simple',\
'tree','urban','very','wood','xylophone','yellow',\
'zebra']
QtGui.QCompleter.__init__(self, myKeywords, parent)
self.connect(self,
QtCore.SIGNAL("activated(const QString&)"), self.changeCompletion)
#|--------------------------End of Constructor---------------------------------|
#|-----------------------------------------------------------------------------|
# changeCompletion
#|-----------------------------------------------------------------------------|
def changeCompletion(self, completion):
if completion.find("(") != -1:
completion = completion[:completion.find("(")]
print(completion)
self.insertText.emit(completion)
#|-----------------------End of changeCompletion-------------------------------|
编辑
附上截图。
如果有人感兴趣,这里是一个“不完整”的解决方案。
这是我所做的。
我已更改为 PlainTextEdit,因为没有显着优势
使用 QTextEdit
编辑
from PyQt5.QtWidgets import QCompleter, QPlainTextEdit
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QTextCursor
import MyCompleter
class AwesomeTextEdit(QPlainTextEdit):
def __init__(self, parent=None):
super(AwesomeTextEdit, self).__init__(parent)
self.completer = MyCompleterparent()
self.completer.setWidget(self)
self.completer.insertText.connect(self.insertCompletion)
def insertCompletion(self, completion):
tc = self.textCursor()
extra = (len(completion) - len(self.completer.completionPrefix()))
tc.movePosition(QTextCursor.Left)
tc.movePosition(QTextCursor.EndOfWord)
tc.insertText(completion[-extra:])
self.setTextCursor(tc)
self.completer.popup().hide()
def focusInEvent(self, event):
if self.completer:
self.completer.setWidget(self)
QPlainTextEdit.focusInEvent(self, event)
def keyPressEvent(self, event):
tc = self.textCursor()
if event.key() == Qt.Key_Tab and self.completer.popup().isVisible():
self.completer.insertText.emit(self.completer.getSelected())
self.completer.setCompletionMode(QCompleter.PopupCompletion)
return
QPlainTextEdit.keyPressEvent(self, event)
tc.select(QTextCursor.WordUnderCursor)
cr = self.cursorRect()
if len(tc.selectedText()) > 0:
self.completer.setCompletionPrefix(tc.selectedText())
popup = self.completer.popup()
popup.setCurrentIndex(self.completer.completionModel().index(0,0))
cr.setWidth(self.completer.popup().sizeHintForColumn(0)
+ self.completer.popup().verticalScrollBar().sizeHint().width())
self.completer.complete(cr)
else:
self.completer.popup().hide()
完成者
from PyQt5.QtWidgets import QCompleter
from PyQt5 import QtCore
class MyCompleter(QCompleter):
insertText = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
QCompleter.__init__(self, ["test","foo","bar"], parent)
self.setCompletionMode(QCompleter.PopupCompletion)
self.highlighted.connect(self.setHighlighted)
def setHighlighted(self, text):
self.lastSelected = text
def getSelected(self):
return self.lastSelected
正在寻找一种使用 QTextEdit 和 QCompleter 进行自动完成的方法。我读过这是可能的,但没有找到任何例子...... 我正在使用 python3.4 和 PyQt5
我正在寻找一个非常基本的示例 感谢您的帮助
这里有一个例子……我已经研究过了……尽管它在 python3.3 和 pyqt4 中。我想它应该不会有太大的不同..
你将不得不改变从PyQt4到从PyQt5
快捷键是 Ctrl+Space 显示建议和 Ctrl+ E 自动完成第一个可行的建议
mMyTextEdit.py
from PyQt4 import QtGui,QtCore
from mMyDictionaryCompleter import MyDictionaryCompleter
#===============================================================================
# MyTextEdit
#===============================================================================
class MyTextEdit(QtGui.QTextEdit):
#|-----------------------------------------------------------------------------|
# class Variables
#|-----------------------------------------------------------------------------|
#no classVariables
# myFocusOutSignal=QtCore.pyqtSignal(str)
#|-----------------------------------------------------------------------------|
# Constructor
#|-----------------------------------------------------------------------------|
def __init__(self,*args):
#*args to set parent
QtGui.QLineEdit.__init__(self,*args)
font=QtGui.QFont()
font.setPointSize(12)
self.setFont(font)
self.completer = None
#|--------------------------End of __init__------------------------------------|
#|-----------------------------------------------------------------------------|
# setCompleter
#|-----------------------------------------------------------------------------|
def setCompleter(self, completer):
if self.completer:
self.disconnect(self.completer, 0, self, 0)
if not completer:
return
completer.setWidget(self)
completer.setCompletionMode(QtGui.QCompleter.PopupCompletion)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.completer = completer
# self.connect(self.completer,
# QtCore.SIGNAL("activated(const QString&)"), self.insertCompletion)
self.completer.insertText.connect(self.insertCompletion)
#|-----------------------End of setCompleter-------------------------------------|
#|-----------------------------------------------------------------------------|
# insertCompletion
#|-----------------------------------------------------------------------------|
def insertCompletion(self, completion):
tc = self.textCursor()
extra = (len(completion) -
len(self.completer.completionPrefix()))
tc.movePosition(QtGui.QTextCursor.Left)
tc.movePosition(QtGui.QTextCursor.EndOfWord)
tc.insertText(completion[-extra:])
self.setTextCursor(tc)
#|-----------------------End of insertCompletion-------------------------------|
#|-----------------------------------------------------------------------------|
# textUnderCursor
#|-----------------------------------------------------------------------------|
def textUnderCursor(self):
tc = self.textCursor()
tc.select(QtGui.QTextCursor.WordUnderCursor)
return tc.selectedText()
#|-----------------------End of textUnderCursor--------------------------------|
#|-----------------------------------------------------------------------------|
# focusInEvent
#|-----------------------------------------------------------------------------|
#---override
def focusInEvent(self, event):
if self.completer:
self.completer.setWidget(self);
QtGui.QTextEdit.focusInEvent(self, event)
#|-----------------------End of focusInEvent-------------------------------------|
#|-----------------------------------------------------------------------------|
# keyPressEvent
#|-----------------------------------------------------------------------------|
#---override
def keyPressEvent(self, event):
if self.completer and self.completer.popup() and self.completer.popup().isVisible():
if event.key() in (
QtCore.Qt.Key_Enter,
QtCore.Qt.Key_Return,
QtCore.Qt.Key_Escape,
QtCore.Qt.Key_Tab,
QtCore.Qt.Key_Backtab):
event.ignore()
return
## has ctrl-Space been pressed??
isShortcut = (event.modifiers() == QtCore.Qt.ControlModifier and\
event.key() == QtCore.Qt.Key_Space)
## modifier to complete suggestion inline ctrl-e
inline = (event.modifiers() == QtCore.Qt.ControlModifier and \
event.key() == QtCore.Qt.Key_E)
## if inline completion has been chosen
if inline:
# set completion mode as inline
self.completer.setCompletionMode(QtGui.QCompleter.InlineCompletion)
completionPrefix = self.textUnderCursor()
if (completionPrefix != self.completer.completionPrefix()):
self.completer.setCompletionPrefix(completionPrefix)
self.completer.complete()
# self.completer.setCurrentRow(0)
# self.completer.activated.emit(self.completer.currentCompletion())
# set the current suggestion in the text box
self.completer.insertText.emit(self.completer.currentCompletion())
# reset the completion mode
self.completer.setCompletionMode(QtGui.QCompleter.PopupCompletion)
return
if (not self.completer or not isShortcut):
pass
QtGui.QTextEdit.keyPressEvent(self, event)
# debug
# print("After controlspace")
# print("isShortcut is: {}".format(isShortcut))
# debug over
## ctrl or shift key on it's own??
ctrlOrShift = event.modifiers() in (QtCore.Qt.ControlModifier ,\
QtCore.Qt.ShiftModifier)
if ctrlOrShift and event.text()== '':
# ctrl or shift key on it's own
return
# debug
# print("After on its own")
# print("isShortcut is: {}".format(isShortcut))
# debug over
# eow = QtCore.QString("~!@#$%^&*()_+{}|:\"<>?,./;'[]\-=") #end of word
# eow = "~!@#$%^&*()_+{}|:\"<>?,./;'[]\-=" #end of word
eow = "~!@#$%^&*+{}|:\"<>?,./;'[]\-=" #end of word
hasModifier = ((event.modifiers() != QtCore.Qt.NoModifier) and\
not ctrlOrShift)
completionPrefix = self.textUnderCursor()
# print('event . text = {}'.format(event.text().right(1)))
# if (not isShortcut and (hasModifier or event.text()=='' or\
# len(completionPrefix) < 3 or \
# eow.contains(event.text().right(1)))):
if not isShortcut :
if self.completer.popup():
self.completer.popup().hide()
return
# print("complPref: {}".format(completionPrefix))
# print("completer.complPref: {}".format(self.completer.completionPrefix()))
# print("mode: {}".format(self.completer.completionMode()))
# if (completionPrefix != self.completer.completionPrefix()):
self.completer.setCompletionPrefix(completionPrefix)
popup = self.completer.popup()
popup.setCurrentIndex(
self.completer.completionModel().index(0,0))
cr = self.cursorRect()
cr.setWidth(self.completer.popup().sizeHintForColumn(0)
+ self.completer.popup().verticalScrollBar().sizeHint().width())
self.completer.complete(cr) ## popup it up!
#|-----------------------End of keyPressEvent----------------------------------|
if __name__ == "__main__":
app = QtGui.QApplication([])
completer = MyDictionaryCompleter()
te = MyTextEdit()
te.setCompleter(completer)
te.show()
app.exec_()
mMyDictionaryCompleter.py
#===============================================================================
# MyDictionaryCompleter
#===============================================================================
from PyQt4 import QtGui, QtCore
class MyDictionaryCompleter(QtGui.QCompleter):
#|-----------------------------------------------------------------------------|
# class Variables
#|-----------------------------------------------------------------------------|
insertText = QtCore.pyqtSignal(str)
#no classVariables
#|-----------------------------------------------------------------------------|
# Constructor
#|-----------------------------------------------------------------------------|
def __init__(self, myKeywords=None,parent=None):
myKeywords =['apple','aggresive','ball','bat','cat','cycle','dog','dumb',\
'elephant','engineer','food','file','good','great',\
'hippopotamus','hyper','india','ireland','just','just',\
'key','kid','lemon','lead','mute','magic',\
'news','newyork','orange','oval','parrot','patriot',\
'question','queue','right','rest','smile','simple',\
'tree','urban','very','wood','xylophone','yellow',\
'zebra']
QtGui.QCompleter.__init__(self, myKeywords, parent)
self.connect(self,
QtCore.SIGNAL("activated(const QString&)"), self.changeCompletion)
#|--------------------------End of Constructor---------------------------------|
#|-----------------------------------------------------------------------------|
# changeCompletion
#|-----------------------------------------------------------------------------|
def changeCompletion(self, completion):
if completion.find("(") != -1:
completion = completion[:completion.find("(")]
print(completion)
self.insertText.emit(completion)
#|-----------------------End of changeCompletion-------------------------------|
编辑
附上截图。
如果有人感兴趣,这里是一个“不完整”的解决方案。 这是我所做的。 我已更改为 PlainTextEdit,因为没有显着优势 使用 QTextEdit
编辑
from PyQt5.QtWidgets import QCompleter, QPlainTextEdit
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QTextCursor
import MyCompleter
class AwesomeTextEdit(QPlainTextEdit):
def __init__(self, parent=None):
super(AwesomeTextEdit, self).__init__(parent)
self.completer = MyCompleterparent()
self.completer.setWidget(self)
self.completer.insertText.connect(self.insertCompletion)
def insertCompletion(self, completion):
tc = self.textCursor()
extra = (len(completion) - len(self.completer.completionPrefix()))
tc.movePosition(QTextCursor.Left)
tc.movePosition(QTextCursor.EndOfWord)
tc.insertText(completion[-extra:])
self.setTextCursor(tc)
self.completer.popup().hide()
def focusInEvent(self, event):
if self.completer:
self.completer.setWidget(self)
QPlainTextEdit.focusInEvent(self, event)
def keyPressEvent(self, event):
tc = self.textCursor()
if event.key() == Qt.Key_Tab and self.completer.popup().isVisible():
self.completer.insertText.emit(self.completer.getSelected())
self.completer.setCompletionMode(QCompleter.PopupCompletion)
return
QPlainTextEdit.keyPressEvent(self, event)
tc.select(QTextCursor.WordUnderCursor)
cr = self.cursorRect()
if len(tc.selectedText()) > 0:
self.completer.setCompletionPrefix(tc.selectedText())
popup = self.completer.popup()
popup.setCurrentIndex(self.completer.completionModel().index(0,0))
cr.setWidth(self.completer.popup().sizeHintForColumn(0)
+ self.completer.popup().verticalScrollBar().sizeHint().width())
self.completer.complete(cr)
else:
self.completer.popup().hide()
完成者
from PyQt5.QtWidgets import QCompleter
from PyQt5 import QtCore
class MyCompleter(QCompleter):
insertText = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
QCompleter.__init__(self, ["test","foo","bar"], parent)
self.setCompletionMode(QCompleter.PopupCompletion)
self.highlighted.connect(self.setHighlighted)
def setHighlighted(self, text):
self.lastSelected = text
def getSelected(self):
return self.lastSelected