Program quit with error when using QCompleterUnable to use in the same application a QWebPage twicefatal error: Python.h: No such file or directoryDerived panel classes in wxpythonwxpython - Erase background erases non-background componentsQcompleter currentCompletion does not workpyqt or pyside Qlistview drag and drop delete itemPossible to have a QCompleter-like appearance without using a QCompleter?How to use PyQt5 QCompleter for code completionQCompleter select data from multiple columnschange style of QCompleter?
How was the blinking terminal cursor invented?
Find the area of the rectangle
How to continually and organically let my readers know what time it is in my story?
Why would company (decision makers) wait for someone to retire, rather than lay them off, when their role is no longer needed?
multiline equation inside a matrix that is a part of multiline equation
How does the Heat Metal spell interact with a follow-up Frostbite spell?
Could a space colony 1g from the sun work?
Would life always name the light from their sun "white"
How can I safely determine the output voltage and current of a transformer?
Why are lawsuits between the President and Congress not automatically sent to the Supreme Court
How can we delete item permanently without storing in Recycle Bin?
What color to choose as "danger" if the main color of my app is red
Does a non-singular matrix have a large minor with disjoint rows and columns and full rank?
"Counterexample" for the Inverse function theorem
When the match time is called, does the current turn end immediately?
Square spiral in Mathematica
What formula to chose a nonlinear formula?
Why is it correct to use ~た in this sentence, even though we're talking about next week?
A person lacking money who shows off a lot
How to deal with the extreme reverberation in big cathedrals when playing the pipe organs?
How does this piece of code determine array size without using sizeof( )?
How come Arya Stark didn't burn in Game of Thrones Season 8 Episode 5
Solenoid fastest possible release - for how long should reversed polarity be applied?
Do high-wing aircraft represent more difficult engineering challenges than low-wing aircraft?
Program quit with error when using QCompleter
Unable to use in the same application a QWebPage twicefatal error: Python.h: No such file or directoryDerived panel classes in wxpythonwxpython - Erase background erases non-background componentsQcompleter currentCompletion does not workpyqt or pyside Qlistview drag and drop delete itemPossible to have a QCompleter-like appearance without using a QCompleter?How to use PyQt5 QCompleter for code completionQCompleter select data from multiple columnschange style of QCompleter?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I'm writing a program with pyqt5 and want to make the QlineEdit show history input by using sqlite to store the inputs. I use a signal to catch the cursor when focusInEvent happens and select the history records at that time, then I put the results into QCompleter so it can pop up in QlineEdit. Now I can make the history inputs show in QlineEdit object but when I click on any value, 1s later, the whole program quit automatically with error, which says "Python has stopped".
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
python pyqt pyqt5 qcompleter
add a comment |
I'm writing a program with pyqt5 and want to make the QlineEdit show history input by using sqlite to store the inputs. I use a signal to catch the cursor when focusInEvent happens and select the history records at that time, then I put the results into QCompleter so it can pop up in QlineEdit. Now I can make the history inputs show in QlineEdit object but when I click on any value, 1s later, the whole program quit automatically with error, which says "Python has stopped".
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
python pyqt pyqt5 qcompleter
1
See How to create a Minimal, Complete, and Verifiable example and modify question accordingly to minimal working example.
– ZF007
Mar 23 at 16:14
add a comment |
I'm writing a program with pyqt5 and want to make the QlineEdit show history input by using sqlite to store the inputs. I use a signal to catch the cursor when focusInEvent happens and select the history records at that time, then I put the results into QCompleter so it can pop up in QlineEdit. Now I can make the history inputs show in QlineEdit object but when I click on any value, 1s later, the whole program quit automatically with error, which says "Python has stopped".
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
python pyqt pyqt5 qcompleter
I'm writing a program with pyqt5 and want to make the QlineEdit show history input by using sqlite to store the inputs. I use a signal to catch the cursor when focusInEvent happens and select the history records at that time, then I put the results into QCompleter so it can pop up in QlineEdit. Now I can make the history inputs show in QlineEdit object but when I click on any value, 1s later, the whole program quit automatically with error, which says "Python has stopped".
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
python pyqt pyqt5 qcompleter
python pyqt pyqt5 qcompleter
edited Mar 23 at 19:56
eyllanesc
92.4k123666
92.4k123666
asked Mar 23 at 15:55
cachekaicachekai
16
16
1
See How to create a Minimal, Complete, and Verifiable example and modify question accordingly to minimal working example.
– ZF007
Mar 23 at 16:14
add a comment |
1
See How to create a Minimal, Complete, and Verifiable example and modify question accordingly to minimal working example.
– ZF007
Mar 23 at 16:14
1
1
See How to create a Minimal, Complete, and Verifiable example and modify question accordingly to minimal working example.
– ZF007
Mar 23 at 16:14
See How to create a Minimal, Complete, and Verifiable example and modify question accordingly to minimal working example.
– ZF007
Mar 23 at 16:14
add a comment |
1 Answer
1
active
oldest
votes
It is difficult to analyze where the problem is without you provide an MCVE, so my response implements what you require without taking into account your current code for it must meet the following requirements:
- You must have 2 tables: objects and history that are related.
- The table objects saves the name of the filtering history, it is similar to the use of the objectName that you use, but in general 2 widgets can access the same history if the connection establishes the same name
- In the history table the information of the words associated with the id of the objects table is saved.
In my example I use the following instructions to create them:
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));
Also to test it I created a data, if you already have data then you must eliminate the if test:
and everything inside.
Finally for a better understanding of my solution I show a QTableView that is changing according to the selection.
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_())
Thanks, my idea was every "focusInEvent" conducts these steps: select history value from sqlite, pass it to "QCompleter" object, then show it on main window. That is to say, the content of "Qcompleter" object is dynamic, not sure if it's achievable or the pyqt only allows "Qcompleter" object to load once during whole process.
– cachekai
Mar 24 at 12:17
@cachekai That's what my code does but with a less intrusive code, the HistoryManager class registers the widgets that you associate with a name of the story similar to what you do with "call_history(self.objectName())", then when the focus change to another QLineEdit will be called again to "call_history(self.objectName())" to select another similar set, with eventFilter you can hear the focusInEvent and focusOutEvent events without having to overwrite the class. Have you tried my code?
– eyllanesc
Mar 24 at 18:14
@cachekai some feedback??
– eyllanesc
Mar 29 at 2:02
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55315595%2fprogram-quit-with-error-when-using-qcompleter%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It is difficult to analyze where the problem is without you provide an MCVE, so my response implements what you require without taking into account your current code for it must meet the following requirements:
- You must have 2 tables: objects and history that are related.
- The table objects saves the name of the filtering history, it is similar to the use of the objectName that you use, but in general 2 widgets can access the same history if the connection establishes the same name
- In the history table the information of the words associated with the id of the objects table is saved.
In my example I use the following instructions to create them:
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));
Also to test it I created a data, if you already have data then you must eliminate the if test:
and everything inside.
Finally for a better understanding of my solution I show a QTableView that is changing according to the selection.
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_())
Thanks, my idea was every "focusInEvent" conducts these steps: select history value from sqlite, pass it to "QCompleter" object, then show it on main window. That is to say, the content of "Qcompleter" object is dynamic, not sure if it's achievable or the pyqt only allows "Qcompleter" object to load once during whole process.
– cachekai
Mar 24 at 12:17
@cachekai That's what my code does but with a less intrusive code, the HistoryManager class registers the widgets that you associate with a name of the story similar to what you do with "call_history(self.objectName())", then when the focus change to another QLineEdit will be called again to "call_history(self.objectName())" to select another similar set, with eventFilter you can hear the focusInEvent and focusOutEvent events without having to overwrite the class. Have you tried my code?
– eyllanesc
Mar 24 at 18:14
@cachekai some feedback??
– eyllanesc
Mar 29 at 2:02
add a comment |
It is difficult to analyze where the problem is without you provide an MCVE, so my response implements what you require without taking into account your current code for it must meet the following requirements:
- You must have 2 tables: objects and history that are related.
- The table objects saves the name of the filtering history, it is similar to the use of the objectName that you use, but in general 2 widgets can access the same history if the connection establishes the same name
- In the history table the information of the words associated with the id of the objects table is saved.
In my example I use the following instructions to create them:
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));
Also to test it I created a data, if you already have data then you must eliminate the if test:
and everything inside.
Finally for a better understanding of my solution I show a QTableView that is changing according to the selection.
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_())
Thanks, my idea was every "focusInEvent" conducts these steps: select history value from sqlite, pass it to "QCompleter" object, then show it on main window. That is to say, the content of "Qcompleter" object is dynamic, not sure if it's achievable or the pyqt only allows "Qcompleter" object to load once during whole process.
– cachekai
Mar 24 at 12:17
@cachekai That's what my code does but with a less intrusive code, the HistoryManager class registers the widgets that you associate with a name of the story similar to what you do with "call_history(self.objectName())", then when the focus change to another QLineEdit will be called again to "call_history(self.objectName())" to select another similar set, with eventFilter you can hear the focusInEvent and focusOutEvent events without having to overwrite the class. Have you tried my code?
– eyllanesc
Mar 24 at 18:14
@cachekai some feedback??
– eyllanesc
Mar 29 at 2:02
add a comment |
It is difficult to analyze where the problem is without you provide an MCVE, so my response implements what you require without taking into account your current code for it must meet the following requirements:
- You must have 2 tables: objects and history that are related.
- The table objects saves the name of the filtering history, it is similar to the use of the objectName that you use, but in general 2 widgets can access the same history if the connection establishes the same name
- In the history table the information of the words associated with the id of the objects table is saved.
In my example I use the following instructions to create them:
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));
Also to test it I created a data, if you already have data then you must eliminate the if test:
and everything inside.
Finally for a better understanding of my solution I show a QTableView that is changing according to the selection.
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_())
It is difficult to analyze where the problem is without you provide an MCVE, so my response implements what you require without taking into account your current code for it must meet the following requirements:
- You must have 2 tables: objects and history that are related.
- The table objects saves the name of the filtering history, it is similar to the use of the objectName that you use, but in general 2 widgets can access the same history if the connection establishes the same name
- In the history table the information of the words associated with the id of the objects table is saved.
In my example I use the following instructions to create them:
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));
Also to test it I created a data, if you already have data then you must eliminate the if test:
and everything inside.
Finally for a better understanding of my solution I show a QTableView that is changing according to the selection.
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_())
answered Mar 24 at 0:58
eyllanesceyllanesc
92.4k123666
92.4k123666
Thanks, my idea was every "focusInEvent" conducts these steps: select history value from sqlite, pass it to "QCompleter" object, then show it on main window. That is to say, the content of "Qcompleter" object is dynamic, not sure if it's achievable or the pyqt only allows "Qcompleter" object to load once during whole process.
– cachekai
Mar 24 at 12:17
@cachekai That's what my code does but with a less intrusive code, the HistoryManager class registers the widgets that you associate with a name of the story similar to what you do with "call_history(self.objectName())", then when the focus change to another QLineEdit will be called again to "call_history(self.objectName())" to select another similar set, with eventFilter you can hear the focusInEvent and focusOutEvent events without having to overwrite the class. Have you tried my code?
– eyllanesc
Mar 24 at 18:14
@cachekai some feedback??
– eyllanesc
Mar 29 at 2:02
add a comment |
Thanks, my idea was every "focusInEvent" conducts these steps: select history value from sqlite, pass it to "QCompleter" object, then show it on main window. That is to say, the content of "Qcompleter" object is dynamic, not sure if it's achievable or the pyqt only allows "Qcompleter" object to load once during whole process.
– cachekai
Mar 24 at 12:17
@cachekai That's what my code does but with a less intrusive code, the HistoryManager class registers the widgets that you associate with a name of the story similar to what you do with "call_history(self.objectName())", then when the focus change to another QLineEdit will be called again to "call_history(self.objectName())" to select another similar set, with eventFilter you can hear the focusInEvent and focusOutEvent events without having to overwrite the class. Have you tried my code?
– eyllanesc
Mar 24 at 18:14
@cachekai some feedback??
– eyllanesc
Mar 29 at 2:02
Thanks, my idea was every "focusInEvent" conducts these steps: select history value from sqlite, pass it to "QCompleter" object, then show it on main window. That is to say, the content of "Qcompleter" object is dynamic, not sure if it's achievable or the pyqt only allows "Qcompleter" object to load once during whole process.
– cachekai
Mar 24 at 12:17
Thanks, my idea was every "focusInEvent" conducts these steps: select history value from sqlite, pass it to "QCompleter" object, then show it on main window. That is to say, the content of "Qcompleter" object is dynamic, not sure if it's achievable or the pyqt only allows "Qcompleter" object to load once during whole process.
– cachekai
Mar 24 at 12:17
@cachekai That's what my code does but with a less intrusive code, the HistoryManager class registers the widgets that you associate with a name of the story similar to what you do with "call_history(self.objectName())", then when the focus change to another QLineEdit will be called again to "call_history(self.objectName())" to select another similar set, with eventFilter you can hear the focusInEvent and focusOutEvent events without having to overwrite the class. Have you tried my code?
– eyllanesc
Mar 24 at 18:14
@cachekai That's what my code does but with a less intrusive code, the HistoryManager class registers the widgets that you associate with a name of the story similar to what you do with "call_history(self.objectName())", then when the focus change to another QLineEdit will be called again to "call_history(self.objectName())" to select another similar set, with eventFilter you can hear the focusInEvent and focusOutEvent events without having to overwrite the class. Have you tried my code?
– eyllanesc
Mar 24 at 18:14
@cachekai some feedback??
– eyllanesc
Mar 29 at 2:02
@cachekai some feedback??
– eyllanesc
Mar 29 at 2:02
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55315595%2fprogram-quit-with-error-when-using-qcompleter%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
See How to create a Minimal, Complete, and Verifiable example and modify question accordingly to minimal working example.
– ZF007
Mar 23 at 16:14