I am currently creating a SQL Editor and Query Wizard with PyQt5 and am running into an issue when trying to add a QCompleter to all my QPlainTextEdits in the wizard. All the UI is created with Qt Designer and is stored in a QStackedWidget.
I have read into Promoting the widget in Designer to my custom widget (TextEdit), which is a QTextEdit with the QCompleter model interface.
My question is, how can one set the completer model to an object that is already created? Is there a way to hold off on initializing it until after the completer is set? In another section of the program, I am able to add the widget after its set due to the functionality, but there must be a better way.
Any help would be greatly appreciated. Below is the code that I use to set the way that works.
tab = QtWidgets.QWidget()
horizontalLayout = QtWidgets.QHBoxLayout(tab)
self.completer = QCompleter(self)
self.all_autocomplete_words.extend(sql_words)
self.all_autocomplete_words = pd.Series(
self.all_autocomplete_words).sort_values().drop_duplicates().tolist()
#print(self.all_autocomplete_words)
completer_model = QStringListModel(self.all_autocomplete_words, self.completer)
self.completer.setModel(completer_model)
self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
self.completer.setWrapAround(False)
# print(self.auto_completion_words)
# print(self.all_autocomplete_words)
self.completingTextEdit = TextEdit(dict_words=self.auto_completion_words,
list_words=self.all_autocomplete_words, parent=tab)
self.completingTextEdit.setCompleter(self.completer)
self.completingTextEdit.setPlaceholderText('SQL Script')
horizontalLayout.addWidget(self.completingTextEdit)
#sql_ws.setPlaceholderText('SQL Script')
self.sql_tab.addTab(tab, key)
Edit:
Here is the base class for the minimum example...
from min_example_fromui import Ui_MainWindow
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QTreeWidget, QTreeWidgetItem, QMenu, QAction, \
QMessageBox, QTreeWidgetItemIterator, QAbstractItemView, QDialog, QShortcut, QGridLayout, QLabel, QLineEdit,\
QPushButton, QWhatsThis, QCompleter, QTextEdit, QProgressDialog, QTableWidgetItem, QTableView
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QFile, QStringListModel, Qt, QThread, pyqtSignal, QObject, pyqtSlot, QTimer, QEventLoop
from PyQt5.QtGui import QCursor, QKeySequence, QTextCursor
import pandas as pd
class sqlWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(sqlWindow, self).__init__(parent)
self.setupUi(self)
self.sql_words = [
'ABORT'
]
self.all_autocomplete_words = []
self.auto_completion_words = {}
self.pushButton.clicked.connect(self.add_tab)
def add_tab(self):
tab = QtWidgets.QWidget()
horizontalLayout = QtWidgets.QHBoxLayout(tab)
self.completer = QCompleter(self)
self.all_autocomplete_words.extend(self.sql_words)
self.all_autocomplete_words = pd.Series(
self.all_autocomplete_words).sort_values().drop_duplicates().tolist()
#print(self.all_autocomplete_words)
completer_model = QStringListModel(self.all_autocomplete_words, self.completer)
self.completer.setModel(completer_model)
self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
self.completer.setWrapAround(False)
# print(self.auto_completion_words)
# print(self.all_autocomplete_words)
self.completingTextEdit = TextEdit(dict_words=self.auto_completion_words,
list_words=self.all_autocomplete_words, parent=tab)
self.completingTextEdit.setCompleter(self.completer)
self.completingTextEdit.setPlaceholderText('SQL Script')
horizontalLayout.addWidget(self.completingTextEdit)
# sql_ws.setPlaceholderText('SQL Script')
self.sql_tab.addTab(tab, 'key')
self.sql_tab.setCurrentWidget(tab)
class TextEdit(QTextEdit):
def __init__(self, dict_words=dict, list_words=list, parent=None):
super(TextEdit, self).__init__(parent)
self._completer = None
self.auto_complete_dict = dict_words
self.all_autocomplete = list_words
#Class Instances
self.completion_prefix = ''
def setCompleter(self, c):
self._completer = c
c.setWidget(self)
c.setCompletionMode(QCompleter.PopupCompletion)
c.setCaseSensitivity(Qt.CaseInsensitive)
c.activated.connect(self.insertCompletion)
def insertCompletion(self, completion):
if self._completer.widget() is not self:
return
tc = self.textCursor()
extra = len(completion) - len(self._completer.completionPrefix())
tc.movePosition(QTextCursor.Left)
tc.movePosition(QTextCursor.EndOfWord)
if self.completion_prefix.lower() == completion[-extra:].lower():
pass
#print('You inserted the word after it was completed')
else:
tc.insertText(completion[-extra:])
#print('The text being inserted',completion[-extra:])
self.setTextCursor(tc)
self._completer.setModel(QStringListModel(self.all_autocomplete, self._completer))
def textUnderCursor(self):
tc = self.textCursor()
tc.select(QTextCursor.WordUnderCursor)
#print('Here is the selected text under the cursor' , tc.selectedText())
return tc.selectedText()
def focusInEvent(self, e):
#Open the widget where you are at in the edit
if self._completer is not None:
self._completer.setWidget(self)
super(TextEdit, self).focusInEvent(e)
def keyPressEvent(self, e):
isShortcut = False
if self._completer is not None and self._completer.popup().isVisible():
#print('Popup is up')
# The following keys are forwarded by the completer to the widget.
if e.key() in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab, Qt.Key_Backtab):
e.ignore()
#self._completer.setModel(QStringListModel(self.all_autocomplete, self._completer))
# Let the completer do default behavior.
return
if e.key() == Qt.Key_E and e.modifiers() == Qt.ControlModifier:
#Control + E was pressed.
words = self.all_autocomplete
self._completer.setModel(QStringListModel(words, self._completer))
isShortcut = True
if e.key() == Qt.Key_Period:
#This is how I will do the lookup functionality. Show when period is his, open the list of options.
self.textCursor().insertText('.')
self.moveCursor(QtGui.QTextCursor.PreviousWord)
self.moveCursor(QtGui.QTextCursor.PreviousWord, QtGui.QTextCursor.KeepAnchor)
dict_key = self.textCursor().selectedText().upper()
#print('Dict Key' , dict_key)
self.moveCursor(QtGui.QTextCursor.NextWord)
self.moveCursor(QtGui.QTextCursor.NextWord)
#print(dict_key)
words = self.auto_complete_dict[dict_key]
self._completer.setModel(QStringListModel(words, self._completer))
isShortcut = True
if self._completer is None or not isShortcut:
# Do not process the shortcut when we have a completer.
super(TextEdit, self).keyPressEvent(e)
ctrlOrShift = e.modifiers() & (Qt.ControlModifier | Qt.ShiftModifier)
if self._completer is None or (ctrlOrShift and len(e.text()) == 0):
return
eow = "~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="
hasModifier = (e.modifiers() != Qt.NoModifier) and not ctrlOrShift
completionPrefix = self.textUnderCursor()
self.completion_prefix = completionPrefix
#print('CompletionPrefix :' , completionPrefix)
if not isShortcut and (hasModifier or len(e.text()) == 0 or len(completionPrefix) < 2 or e.text()[-1] in eow):
self._completer.popup().hide()
return
if completionPrefix != self._completer.completionPrefix():
#Puts the Prefix of the word youre typing into the Prefix
self._completer.setCompletionPrefix(completionPrefix)
self._completer.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)
if __name__ == "__main__":
import sys
'''These excepthook lines are to catch errors when using pyqt5'''
sys._excepthook = sys.excepthook
def exception_hook(exctype, value, traceback):
print(exctype, value, traceback)
sys._excepthook(exctype, value, traceback)
sys.exit(1)
sys.excepthook = exception_hook
'''Error handling section to raise errors'''
app = QApplication(sys.argv)
main_window = sqlWindow()
main_window.show()
sys.exit(app.exec_())
And here is my ui code:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.sql_tab = QtWidgets.QTabWidget(self.centralwidget)
self.sql_tab.setEnabled(True)
self.sql_tab.setTabsClosable(True)
self.sql_tab.setMovable(True)
self.sql_tab.setObjectName("sql_tab")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
self.gridLayout_2 = QtWidgets.QGridLayout(self.tab)
self.gridLayout_2.setObjectName("gridLayout_2")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout_2.addItem(spacerItem, 0, 2, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout_2.addItem(spacerItem1, 0, 0, 1, 1)
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.label_2 = QtWidgets.QLabel(self.tab)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1)
self.pushButton = QtWidgets.QPushButton(self.tab)
self.pushButton.setObjectName("pushButton")
self.gridLayout.addWidget(self.pushButton, 0, 1, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 1, 1, 1, 1)
self.label = QtWidgets.QLabel(self.tab)
self.label.setFrameShape(QtWidgets.QFrame.Box)
self.label.setLineWidth(0)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.gridLayout_2.addWidget(self.label, 0, 1, 1, 1)
self.sql_tab.addTab(self.tab, "")
self.verticalLayout.addWidget(self.sql_tab)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.sql_tab.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label_2.setText(_translate("MainWindow", "For Help, refer to the User Manual."))
self.pushButton.setText(_translate("MainWindow", "User Manual"))
self.label.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:18pt;\">SQL Editor Welcome Sheet</span></p><p><br/></p><p>Only List Reports Can be Ran by Worksheet. </p><p>All Other Reports are Ran Through the Query Builder.</p></body></html>"))
self.sql_tab.setTabText(self.sql_tab.indexOf(self.tab), _translate("MainWindow", "SQL Editor Home"))
Thanks!
Second Edit:
from min_example_fromui import Ui_MainWindow
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QTreeWidget, QTreeWidgetItem, QMenu, QAction, \
QMessageBox, QTreeWidgetItemIterator, QAbstractItemView, QDialog, QShortcut, QGridLayout, QLabel, QLineEdit,\
QPushButton, QWhatsThis, QCompleter, QTextEdit, QProgressDialog, QTableWidgetItem, QTableView
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QFile, QStringListModel, Qt, QThread, pyqtSignal, QObject, pyqtSlot, QTimer, QEventLoop
from PyQt5.QtGui import QCursor, QKeySequence, QTextCursor
import pandas as pd
class sqlWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(sqlWindow, self).__init__(parent)
self.setupUi(self)
self.sql_words = [
'ABORT'
]
self.all_autocomplete_words = []
self.auto_completion_words = {}
self.pushButton.clicked.connect(self.add_tab)
self.completer = QCompleter(self)
self.all_autocomplete_words.extend(self.sql_words)
self.all_autocomplete_words = pd.Series(
self.all_autocomplete_words).sort_values().drop_duplicates().tolist()
# print(self.all_autocomplete_words)
self.completer_model = QStringListModel(self.all_autocomplete_words, self.completer)
self.completer.setModel(self.completer_model)
self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
self.completer.setWrapAround(False)
self.my_sqlbox = TextEdit(dict_words=self.auto_completion_words,
list_words=self.all_autocomplete_words, parent=None)
self.my_sqlbox.setCompleter(self.completer)
self.my_sqlbox.setPlaceholderText('SQL Script')
def add_tab(self):
tab = QtWidgets.QWidget()
horizontalLayout = QtWidgets.QHBoxLayout(tab)
self.completingTextEdit = TextEdit(dict_words=self.auto_completion_words,
list_words=self.all_autocomplete_words, parent=tab)
self.completingTextEdit.setCompleter(self.completer)
self.completingTextEdit.setPlaceholderText('SQL Script')
horizontalLayout.addWidget(self.completingTextEdit)
# sql_ws.setPlaceholderText('SQL Script')
self.sql_tab.addTab(tab, 'key')
self.sql_tab.setCurrentWidget(tab)
class TextEdit(QTextEdit):
def __init__(self, dict_words=dict, list_words=list, parent=None):
super(TextEdit, self).__init__(parent)
self._completer = None
self.auto_complete_dict = dict_words
self.all_autocomplete = list_words
#Class Instances
self.completion_prefix = ''
def setCompleter(self, c):
self._completer = c
c.setWidget(self)
c.setCompletionMode(QCompleter.PopupCompletion)
c.setCaseSensitivity(Qt.CaseInsensitive)
c.activated.connect(self.insertCompletion)
def insertCompletion(self, completion):
if self._completer.widget() is not self:
return
tc = self.textCursor()
extra = len(completion) - len(self._completer.completionPrefix())
tc.movePosition(QTextCursor.Left)
tc.movePosition(QTextCursor.EndOfWord)
if self.completion_prefix.lower() == completion[-extra:].lower():
pass
#print('You inserted the word after it was completed')
else:
tc.insertText(completion[-extra:])
#print('The text being inserted',completion[-extra:])
self.setTextCursor(tc)
self._completer.setModel(QStringListModel(self.all_autocomplete, self._completer))
def textUnderCursor(self):
tc = self.textCursor()
tc.select(QTextCursor.WordUnderCursor)
#print('Here is the selected text under the cursor' , tc.selectedText())
return tc.selectedText()
def focusInEvent(self, e):
#Open the widget where you are at in the edit
if self._completer is not None:
self._completer.setWidget(self)
super(TextEdit, self).focusInEvent(e)
def keyPressEvent(self, e):
isShortcut = False
if self._completer is not None and self._completer.popup().isVisible():
#print('Popup is up')
# The following keys are forwarded by the completer to the widget.
if e.key() in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab, Qt.Key_Backtab):
e.ignore()
#self._completer.setModel(QStringListModel(self.all_autocomplete, self._completer))
# Let the completer do default behavior.
return
if e.key() == Qt.Key_E and e.modifiers() == Qt.ControlModifier:
#Control + E was pressed.
words = self.all_autocomplete
self._completer.setModel(QStringListModel(words, self._completer))
isShortcut = True
if e.key() == Qt.Key_Period:
#This is how I will do the lookup functionality. Show when period is his, open the list of options.
self.textCursor().insertText('.')
self.moveCursor(QtGui.QTextCursor.PreviousWord)
self.moveCursor(QtGui.QTextCursor.PreviousWord, QtGui.QTextCursor.KeepAnchor)
dict_key = self.textCursor().selectedText().upper()
#print('Dict Key' , dict_key)
self.moveCursor(QtGui.QTextCursor.NextWord)
self.moveCursor(QtGui.QTextCursor.NextWord)
#print(dict_key)
words = self.auto_complete_dict[dict_key]
self._completer.setModel(QStringListModel(words, self._completer))
isShortcut = True
if self._completer is None or not isShortcut:
# Do not process the shortcut when we have a completer.
super(TextEdit, self).keyPressEvent(e)
ctrlOrShift = e.modifiers() & (Qt.ControlModifier | Qt.ShiftModifier)
if self._completer is None or (ctrlOrShift and len(e.text()) == 0):
return
eow = "~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="
hasModifier = (e.modifiers() != Qt.NoModifier) and not ctrlOrShift
completionPrefix = self.textUnderCursor()
self.completion_prefix = completionPrefix
#print('CompletionPrefix :' , completionPrefix)
if not isShortcut and (hasModifier or len(e.text()) == 0 or len(completionPrefix) < 2 or e.text()[-1] in eow):
self._completer.popup().hide()
return
if completionPrefix != self._completer.completionPrefix():
#Puts the Prefix of the word youre typing into the Prefix
self._completer.setCompletionPrefix(completionPrefix)
self._completer.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)
if __name__ == "__main__":
import sys
'''These excepthook lines are to catch errors when using pyqt5'''
sys._excepthook = sys.excepthook
def exception_hook(exctype, value, traceback):
print(exctype, value, traceback)
sys._excepthook(exctype, value, traceback)
sys.exit(1)
sys.excepthook = exception_hook
'''Error handling section to raise errors'''
app = QApplication(sys.argv)
main_window = sqlWindow()
main_window.show()
sys.exit(app.exec_())
Static QPlainText from ui
So for those in the future who run into this problem, I attempted to promote the widget in Qt Designer. However, I ran into issues when trying to add the arguments for the QCompleter. What I had to end up doing was to remove the QPlainTextEdit upon load and then call a function to add the new TextEdit class that I created along with the QCompleter.
See code below:
from min_example_fromui import Ui_MainWindow
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QTreeWidget, QTreeWidgetItem, QMenu, QAction, \
QMessageBox, QTreeWidgetItemIterator, QAbstractItemView, QDialog, QShortcut, QGridLayout, QLabel, QLineEdit,\
QPushButton, QWhatsThis, QCompleter, QTextEdit, QProgressDialog, QTableWidgetItem, QTableView
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QFile, QStringListModel, Qt, QThread, pyqtSignal, QObject, pyqtSlot, QTimer, QEventLoop
from PyQt5.QtGui import QCursor, QKeySequence, QTextCursor
import pandas as pd
class sqlWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(sqlWindow, self).__init__(parent)
self.setupUi(self)
self.sql_words = [
'ABORT'
]
self.all_autocomplete_words = []
self.auto_completion_words = {}
##################Delete the existing QPlainTextEdit############
self.my_sqlbox.deleteLater()
self.pushButton.clicked.connect(self.add_tab)
self.pushButton_2.clicked.connect(self.test)
self.completer = QCompleter(self)
self.all_autocomplete_words.extend(self.sql_words)
self.all_autocomplete_words = pd.Series(
self.all_autocomplete_words).sort_values().drop_duplicates().tolist()
# print(self.all_autocomplete_words)
self.completer_model = QStringListModel(self.all_autocomplete_words, self.completer)
self.completer.setModel(self.completer_model)
self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
self.completer.setWrapAround(False)
#######RIGHT HERE IS WHERE I CALL THE NEW TextEdit creation#######
self.makeText()
def add_tab(self):
tab = QtWidgets.QWidget()
horizontalLayout = QtWidgets.QHBoxLayout(tab)
self.completingTextEdit = TextEdit(dict_words=self.auto_completion_words,
list_words=self.all_autocomplete_words, parent=tab)
self.completingTextEdit.setCompleter(self.completer)
self.completingTextEdit.setPlaceholderText('SQL Script')
horizontalLayout.addWidget(self.completingTextEdit)
# sql_ws.setPlaceholderText('SQL Script')
self.sql_tab.addTab(tab, 'key')
self.sql_tab.setCurrentWidget(tab)
def makeText(self):
self.my_sqlbox = TextEdit(dict_words=self.auto_completion_words,
list_words=self.all_autocomplete_words, parent=None)
self.my_sqlbox.setCompleter(self.completer)
self.my_sqlbox.setPlaceholderText('SQL Script')
self.gridLayout_2.addWidget(self.my_sqlbox ,0, 1, 1, 1)
class TextEdit(QTextEdit):
def __init__(self, dict_words=dict, list_words=list, parent=None):
super(TextEdit, self).__init__(parent)
self._completer = None
self.auto_complete_dict = dict_words
self.all_autocomplete = list_words
#Class Instances
self.completion_prefix = ''
def setCompleter(self, c):
self._completer = c
c.setWidget(self)
c.setCompletionMode(QCompleter.PopupCompletion)
c.setCaseSensitivity(Qt.CaseInsensitive)
c.activated.connect(self.insertCompletion)
def insertCompletion(self, completion):
if self._completer.widget() is not self:
return
tc = self.textCursor()
extra = len(completion) - len(self._completer.completionPrefix())
tc.movePosition(QTextCursor.Left)
tc.movePosition(QTextCursor.EndOfWord)
if self.completion_prefix.lower() == completion[-extra:].lower():
pass
#print('You inserted the word after it was completed')
else:
tc.insertText(completion[-extra:])
#print('The text being inserted',completion[-extra:])
self.setTextCursor(tc)
self._completer.setModel(QStringListModel(self.all_autocomplete, self._completer))
def textUnderCursor(self):
tc = self.textCursor()
tc.select(QTextCursor.WordUnderCursor)
#print('Here is the selected text under the cursor' , tc.selectedText())
return tc.selectedText()
def focusInEvent(self, e):
#Open the widget where you are at in the edit
if self._completer is not None:
self._completer.setWidget(self)
super(TextEdit, self).focusInEvent(e)
def keyPressEvent(self, e):
isShortcut = False
if self._completer is not None and self._completer.popup().isVisible():
#print('Popup is up')
# The following keys are forwarded by the completer to the widget.
if e.key() in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab, Qt.Key_Backtab):
e.ignore()
#self._completer.setModel(QStringListModel(self.all_autocomplete, self._completer))
# Let the completer do default behavior.
return
if e.key() == Qt.Key_E and e.modifiers() == Qt.ControlModifier:
#Control + E was pressed.
words = self.all_autocomplete
self._completer.setModel(QStringListModel(words, self._completer))
isShortcut = True
if e.key() == Qt.Key_Period:
#This is how I will do the lookup functionality. Show when period is his, open the list of options.
self.textCursor().insertText('.')
self.moveCursor(QtGui.QTextCursor.PreviousWord)
self.moveCursor(QtGui.QTextCursor.PreviousWord, QtGui.QTextCursor.KeepAnchor)
dict_key = self.textCursor().selectedText().upper()
#print('Dict Key' , dict_key)
self.moveCursor(QtGui.QTextCursor.NextWord)
self.moveCursor(QtGui.QTextCursor.NextWord)
#print(dict_key)
words = self.auto_complete_dict[dict_key]
self._completer.setModel(QStringListModel(words, self._completer))
isShortcut = True
if self._completer is None or not isShortcut:
# Do not process the shortcut when we have a completer.
super(TextEdit, self).keyPressEvent(e)
ctrlOrShift = e.modifiers() & (Qt.ControlModifier | Qt.ShiftModifier)
if self._completer is None or (ctrlOrShift and len(e.text()) == 0):
return
eow = "~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="
hasModifier = (e.modifiers() != Qt.NoModifier) and not ctrlOrShift
completionPrefix = self.textUnderCursor()
self.completion_prefix = completionPrefix
#print('CompletionPrefix :' , completionPrefix)
if not isShortcut and (hasModifier or len(e.text()) == 0 or len(completionPrefix) < 2 or e.text()[-1] in eow):
self._completer.popup().hide()
return
if completionPrefix != self._completer.completionPrefix():
#Puts the Prefix of the word youre typing into the Prefix
self._completer.setCompletionPrefix(completionPrefix)
self._completer.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)
if __name__ == "__main__":
import sys
'''These excepthook lines are to catch errors when using pyqt5'''
sys._excepthook = sys.excepthook
def exception_hook(exctype, value, traceback):
print(exctype, value, traceback)
sys._excepthook(exctype, value, traceback)
sys.exit(1)
sys.excepthook = exception_hook
'''Error handling section to raise errors'''
app = QApplication(sys.argv)
main_window = sqlWindow()
main_window.show()
sys.exit(app.exec_())