PyQt5 Добавление QCompleter к существующему QTextEdit - PullRequest
0 голосов
/ 28 февраля 2020

В настоящее время я создаю SQL редактор и мастер запросов с PyQt5 и столкнулся с проблемой при попытке добавить QCompleter ко всем моим QPlainTextEdits в мастере. Весь пользовательский интерфейс создается с помощью Qt Designer и хранится в QStackedWidget.

Я прочитал в Повышение виджета в Designer до моего пользовательского виджета (TextEdit), который является QTextEdit с интерфейсом модели QCompleter.

Мой вопрос: как можно установить завершенную модель для объекта, который уже создан? Есть ли способ отложить инициализацию до тех пор, пока не будет установлен завершитель? В другом разделе программы я могу добавить виджет после его установки из-за функциональности, но должен быть лучший способ.

Любая помощь будет принята с благодарностью. Ниже приведен код, который я использую для установки способа работы.

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)

Редактировать:

Вот базовый класс для минимального примера ...

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_())

А вот мой код пользовательского интерфейса:

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"))

Спасибо!

Второе редактирование:

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_())

Stati c QPlainText от пользовательского интерфейса

1 Ответ

0 голосов
/ 04 марта 2020

Поэтому для тех, кто столкнется с этой проблемой в будущем, я попытался продвинуть виджет в Qt Designer. Однако я столкнулся с проблемами при попытке добавить аргументы для QCompleter. В итоге мне пришлось удалить QPlainTextEdit при загрузке, а затем вызвать функцию для добавления нового класса TextEdit, который я создал вместе с QCompleter.

См. Код ниже:

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_())
...