程序在使用质量控制时退出并出错



我正在使用pyqt5编写一个程序,并希望通过使用sqlite来存储输入来使QlineEdit显示历史记录输入。当focusInEvent发生时,我使用信号来捕获光标并选择当时的历史记录,然后将结果放入QCompleter中,以便它可以在QlineEdit中弹出。现在我可以让历史输入显示在 QlineEdit 对象中,但是当我单击任何值时,1 秒后,整个程序会自动退出并显示错误,显示"Python 已停止"。

class FocusLineEdit(QLineEdit):
    ac = pyqtSignal(list)
    def __init__(self, parent=None):
        super(FocusLineEdit, self).__init__(parent)
        self.ac.connect(self.addCompleter)
    def focusInEvent(self, event):
        rtl = call_history(self.objectName())
        self.ac.emit(rtl)
    def addCompleter(self, rtl):
        self.autoCompleter = QCompleter(rtl)
        self.autoCompleter.setCompletionMode(1)
        self.setCompleter(self.autoCompleter)
    def focusOutEvent(self, event):
        pass

如果没有您提供 MCVE,很难分析问题出在哪里,因此我的响应在不考虑您当前代码的情况下实现了您的要求,因为它必须满足以下要求:

  • 您必须有 2 个表:相关的对象和历史记录。
  • 表对象保存过滤历史的名称,它类似于您使用的对象名称的使用,但一般来说,如果连接建立相同的名称,则 2 个小部件可以访问相同的历史记录
  • 在历史记录表中,将保存与对象表的 id 关联的单词的信息。

在我的示例中,我使用以下说明来创建它们:

CREATE TABLE IF NOT EXISTS objects (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE);
CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY AUTOINCREMENT, id_object INTEGER REFERENCES objects (id), word TEXT NOT NULL, UNIQUE (id_object, word));

同样为了测试它,我创建了一个数据,如果您已经有数据,则必须消除if test:和里面的所有内容。

最后,为了更好地理解我的解决方案,我展示了一个根据选择而变化的 QTableView。

from PyQt5 import QtCore, QtGui, QtWidgets, QtSql
def createConnection():
    db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
    db_path = 'test.db'
    db.setDatabaseName(db_path)
    if not db.open():
        QMessageBox.critical(None, qApp.tr("Cannot open database"),
                             qApp.tr("Unable to establish a database connection.n"
                                     "This example needs SQLite support. Please read "
                                     "the Qt SQL driver documentation for information "
                                     "how to build it.nn"
                                     "Click Cancel to exit."),
                             QMessageBox.Cancel)
        return False
    test = True
    if test:
        query = QtSql.QSqlQuery()
        if not query.exec_('CREATE TABLE IF NOT EXISTS objects (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE);'):
            return False
        if not query.exec_('CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY AUTOINCREMENT, id_object INTEGER REFERENCES objects (id), word TEXT NOT NULL, UNIQUE (id_object, word));'):
            return False
        for i in range(3):
            query.prepare('INSERT INTO objects (name) VALUES (?)')
            query.addBindValue("obj{}".format(i))
            if not query.exec_():
                print(query.lastError().text())
        import requests
        import random
        word_site = "http://svnweb.freebsd.org/csrg/share/dict/words?view=co&content-type=text/plain"
        response = requests.get(word_site)
        WORDS = response.content.decode().splitlines()
        print(WORDS)
        for i in range(3):
            for text in random.sample(WORDS, 50):
                query.prepare('INSERT INTO history (id_object, word) VALUES (?, ?)')
                query.addBindValue(i+1)
                query.addBindValue(text)
                if not query.exec_():
                    print(query.lastError().text())
    return True
class Completer(QtWidgets.QCompleter):
    def __init__(self, parent=None):
        super(Completer, self).__init__(parent)
        self._last_words = []
    def splitPath(self, path):
        if path[-1] != ' ':
            words = path.split()
            self._last_words = words[:-1] if len(words) > 1 else []
            return [words[-1]]
        else:
            QtCore.QTimer.singleShot(0, self.popup().hide)
            return []
    def pathFromIndex(self, index):
        val = super(Completer, self).pathFromIndex(index)
        return ' '.join(self._last_words + [val])
class HistoryManager(QtCore.QObject):
    nameChanged = QtCore.pyqtSignal(str)
    def __init__(self, parent=None):
        super(HistoryManager, self).__init__(parent)
        model = QtSql.QSqlRelationalTableModel(self)
        model.setTable("history")
        model.setRelation(1, QtSql.QSqlRelation("objects", "id", "name"))
        model.select()
        self._proxy = QtCore.QSortFilterProxyModel(self)
        self._proxy.setSourceModel(model)
        self._proxy.setFilterKeyColumn(1)
        # proxy.setFilterFixedString("obj1")
        self._widgets = {}
        self._completer = Completer(self)
        self._completer.setModel(self._proxy)
        self._completer.setCompletionColumn(2)
    def register_widget(self, widget, objectname):
        # TODO
        if callable(getattr(widget, "setCompleter")):
            widget.installEventFilter(self)
            self._widgets[widget] = objectname
            return True
        return False
    def eventFilter(self, obj, event):
        if obj in self._widgets:
            if event.type() == QtCore.QEvent.FocusIn:
                name = self._widgets[obj]
                self._proxy.setFilterFixedString(name)
                obj.setCompleter(self._completer)
                self.nameChanged.emit(name)
            elif event.type() == QtCore.QEvent.FocusOut:
                obj.setCompleter(None)
                self._proxy.setFilterFixedString("")
                self.nameChanged.emit("")
        return super(HistoryManager, self).eventFilter(obj, event)
class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self._manager = HistoryManager()
        model = QtSql.QSqlRelationalTableModel(self)
        model.setTable("history")
        model.setRelation(1, QtSql.QSqlRelation("objects", "id", "name"))
        model.select()
        self._proxy = QtCore.QSortFilterProxyModel(self)
        self._proxy.setSourceModel(model)
        self._proxy.setFilterKeyColumn(1)
        tv = QtWidgets.QTableView()
        tv.setModel(self._proxy)
        vlay = QtWidgets.QVBoxLayout()
        for i in range(3):
            le = QtWidgets.QLineEdit()
            vlay.addWidget(le)
            self._manager.register_widget(le, "obj{}".format(i))
        vlay.addStretch()
        lay = QtWidgets.QHBoxLayout(self)
        lay.addWidget(tv, stretch=1)
        lay.addLayout(vlay)
        self._manager.nameChanged.connect(self._proxy.setFilterFixedString)
if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    if not createConnection():
        sys.exit(-1)
    manager = HistoryManager()
    w = Widget()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

相关内容

  • 没有找到相关文章

最新更新