нет ключевых слов python в предложениях автозаполнения с использованием QScintilla и PyQt

Я ожидал автозаполнения ключевых слов Python (например, for, range, lambda) и надеялся на предложения автозаполнения стандартных библиотечных модулей и функций (например, sys, os.path и т. д.) при настройке API с помощью лексера QsciLexerPython, но в приведенном ниже примере кода сжато и обновлено с этого веб-сайта, единственного автозаполнения что происходит, четыре строки добавляются в список.

Я делаю что-то не так, и если да, то как мне заставить ключевые слова python регистрироваться в автозаполнении? (мой главный вопрос здесь, конечно)

Если это ожидаемое поведение, то какую роль играет лексер в автозаполнении и почему ключевые слова из лексера не назначаются спискам автозаполнения в этом примере?

Наконец, возможно ли иметь стандартные библиотечные модули и подмодули Python в автозаполнении, и что для этого требуется?

"""Base code originally from: http://kib2.free.fr/tutos/PyQt4/QScintilla2.html"""

import sys
from PyQt5 import QtWidgets, Qsci

app = QtWidgets.QApplication(sys.argv)
editor = Qsci.QsciScintilla()
lexer = Qsci.QsciLexerPython()
editor.setLexer(lexer)

## setup autocompletion
api = Qsci.QsciAPIs(lexer)
api.add("aLongString")
api.add("aLongerString")
api.add("aDifferentString")
api.add("sOmethingElse")
api.prepare()
editor.setAutoCompletionThreshold(1)
editor.setAutoCompletionSource(Qsci.QsciScintilla.AcsAPIs)

editor.show()
editor.setText(open(sys.argv[0]).read())
sys.exit(app.exec_())

person Vince W.    schedule 11.10.2017    source источник
comment
Нет необходимости добавлять ключевые слова напрямую. Существуют файлы Python API, предоставляемые стандартной установкой qscintilla, которые можно загружать во время выполнения. Вы также можете загрузить файлы API для pyqt и для самой qscintilla.   -  person ekhumoro    schedule 12.10.2017
comment
@ekhumoro Глядя в пакет, я вижу эти файлы API, но я не уверен, что вызывает функцию для их загрузки. Не могли бы вы привести пример?   -  person Vince W.    schedule 12.10.2017
comment
Спасибо за комментарий, я более внимательно изучил документацию по классам и нашел то, что искал. Смотрите ответ ниже. pyqt.sourceforge.net/Docs/QScintilla2/classQsciAPIs.html   -  person Vince W.    schedule 12.10.2017
comment
Извините - я собирался добавить ответ, но вы меня опередили :)   -  person ekhumoro    schedule 12.10.2017


Ответы (2)


Спасибо ekhumoro за то, что подсказал мне ответ. Класс QsciAPIs имеет метод загрузки, а PyQt поставляется с набором файлов API. Ниже приведен код, который выполняет правильное автозаполнение так, как я искал:

"""Base code originally from: http://kib2.free.fr/tutos/PyQt4/QScintilla2.html"""

import sys
import os
import PyQt5
from PyQt5 import QtWidgets, Qsci

app = QtWidgets.QApplication(sys.argv)
editor = Qsci.QsciScintilla()
lexer = Qsci.QsciLexerPython(editor)
editor.setLexer(lexer)

## setup autocompletion
api = Qsci.QsciAPIs(lexer)

# import the desired api file
pyqt_path = os.path.dirname(PyQt5.__file__)
api.load(os.path.join(pyqt_path, "Qt/qsci/api/python/Python-3.6.api"))

api.prepare()
editor.setAutoCompletionThreshold(1)
editor.setAutoCompletionSource(Qsci.QsciScintilla.AcsAll)

editor.show()
editor.setText(open(sys.argv[0]).read())
sys.exit(app.exec_())
person Vince W.    schedule 11.10.2017
comment
Обратите внимание, что вы можете получить список всех установленных файлов API из api.installedAPIFiles(). Если вам нужны ключевые слова языка для python, вы можете добавить их по отдельности из lexer.keywords(1).split(). - person ekhumoro; 12.10.2017
comment
Привет @ekhumoro, не могли бы вы дать больше пояснений о том, что на самом деле делает функция api.load(..)? Насколько я понимаю, он клонирует ключевые слова из данного API-файла. Будет ли api.installedAPIFiles() просто возвращать те имена файлов, которые были клонированы ранее? Я хотел бы добавить ваши пояснения на свой веб-сайт qscintilla.com/autocompletion. - person K.Mulier; 08.11.2017
comment
@ekhumoro, если вы согласны, я буду правильно ссылаться на вашу учетную запись StackOverflow при добавлении ваших объяснений на веб-сайт ;-) - person K.Mulier; 08.11.2017
comment
@ К.Мулье. Необработанные файлы API устанавливаются в стандартную системную папку (обычно в каталог общих данных qt). Метод api.load() считывает необработанный файл API и сохраняет его во внутреннем списке. Метод api.prepare() выполняет фактическую работу по анализу строк необработанных данных и сохранению информации в формате, к которому можно получить эффективный доступ. Подготовленные данные можно сохранить с помощью api.savePrepared() и повторно загрузить с помощью api.loadPrepared(). Эти подготовленные файлы данных обычно хранятся приложением в каталоге конфигурации для каждого пользователя. - person ekhumoro; 08.11.2017
comment
@ К.Мулье. Спасибо за предложение, но в основном я просто передаю информацию, которую нашел в другом месте. Вы делаете всю реальную работу по созданию и поддержке веб-сайта. Если вы хотите отдать должное там, где это необходимо, убедитесь, что вы четко указываете Фила Томпсона (Riverbank Computing), так как он является автором QScintilla, а также предоставляет привязки PyQt. Возможно, вам также следует предоставить заметную ссылку на официальную документацию QScintilla. - person ekhumoro; 08.11.2017
comment
Привет @ekhumoro. Спасибо за ваш ответ. Я добавил ссылку на свою домашнюю страницу на сайт по сбору средств Нила Ходжсона (создателя Scintilla). Спасибо за указание на работу мистера Фила Томпсона. Как вы объяснили, без мистера Томпсона мы не смогли бы использовать Scintilla в Python (и PyQt). Вы знаете о его странице по сбору средств для его работы над QScintilla и привязками PyQt? - person K.Mulier; 08.11.2017
comment
@ К.Мулье. QScintilla делает намного больше, чем просто обертка Scintilla для Qt. Ваша вводная страница действительно вводит в заблуждение. См. страницу лицензии QScintilla, чтобы узнать о его коммерческом статусе. Также кажется несколько странным упоминать Nokia — мало кто будет вспоминать этот эпизод в истории Qt с большой любовью. В настоящее время Qt принадлежит Digia/The Qt Company. - person ekhumoro; 09.11.2017
comment
Привет @ekhumoro, я рад получить ваши отзывы о сайте. У меня сложилось впечатление, что QScintilla делает только оболочку Scintilla для Qt (или, в частности, PyQt). Но, видимо, мое впечатление ошибочно, и QScintilla делает больше. Пожалуйста, поделитесь со мной дополнительной информацией, чтобы я мог исправить вступление на своем веб-сайте. - person K.Mulier; 10.11.2017
comment
@ К.Мулье. Я не хочу придавать этому слишком большое значение, но я думаю, что, по крайней мере, это просто проявление вежливости — признать главного автора QScintilla. Если вы собираетесь создать веб-сайт под названием QScintilla, использующий домен qscintilla.com, я думаю, что на вас лежит ответственность за соблюдение авторских прав автора. Если вы хотите узнать, из чего состоит QScintilla, вы можете скачать исходный код и убедиться в этом сами. Существует также список рассылки QScintilla. - person ekhumoro; 10.11.2017
comment
Привет @ekhumoro, ты прав. Я должен сделать это. Где я могу найти информацию о вещах, которые QScintilla добавляет поверх Scintilla (помимо чтения обоих исходных кодов)? - person K.Mulier; 10.11.2017
comment
@ К.Мулье. список классов должен дать вам общее представление о том, что включено. Действительно, высокоуровневые API QScintilla больше похожи на SciTE, чем на Scintilla. API-интерфейсы Scintilla в основном очень низкоуровневые. Поверх него нужно добавить множество слоев, чтобы использовать все его функции. QScintilla изначально создавался исключительно для использования в IDE Eric Python, но с тех пор жизнь своя. - person ekhumoro; 10.11.2017
comment
Интересно, не знал, что QScintilla изначально создавалась для Eric Python IDE :-) - person K.Mulier; 10.11.2017
comment
Как вы всему этому научились? У вас есть личный проект (возможно, IDE) на базе QScintilla? - person K.Mulier; 10.11.2017
comment
@ К.Мулье. Я использую как PyQt, так и QScintilla по-разному примерно с того времени, когда Qt3 был впервые выпущен (в 2002 году). Так что я полагаю, что просто постепенно накапливал знания в течение многих лет. Однако никакого реального плана по этому поводу не было ;-) (PS: я думаю, что нам, вероятно, следует закончить это обсуждение здесь, поскольку мы похищаем ответ Винса В.). - person ekhumoro; 10.11.2017
comment
Да, ты прав. Возможно, мы можем продолжить по электронной почте? Я оставлю здесь свой адрес электронной почты, вы его запишите, а затем я немедленно удалю этот комментарий: kristof dot mulier at telenet dot be - person K.Mulier; 10.11.2017
comment
@ К.Мулье. Чат на SO был бы лучше. - person ekhumoro; 10.11.2017
comment
Не знаю.. пока особо не пользовался. Будут ли сообщения, которыми мы обмениваемся в чате, сохраняться для дальнейшего использования? Я имею в виду, мне нравится иметь возможность искать разговоры, если я забыл что-то интересное. С почтой это возможно. - person K.Mulier; 10.11.2017
comment
@K.Mulier, и ekhumoro, просто чтобы вы знали, мне нравилось читать туда-сюда. Любопытство никогда не умирает. В качестве примечания, я задал этот вопрос после проверки qscintilla.com и не нашел ответа, поэтому я рад, что это вызвало некоторую дискуссию. - person Vince W.; 10.11.2017
comment
@ВинсВ. рад слышать :-) - person K.Mulier; 10.11.2017

qscintilla не знает ни ключевых слов python, ни библиотек, QsciAPIs надеется, что вы предоставите информацию, в следующей части я покажу некоторые функции, которые возвращают ключевые слова и имена стандартных библиотек. qscintilla будет выполнять автозаполнение только со словами, которые вы предоставляете. Если вам нужно интеллектуальное автозаполнение, я рекомендую вам использовать логику, которая распознает точки или скобки и фильтрует слова, которые вы предоставляете QsciAPI.

import sys
from PyQt5 import QtWidgets, Qsci
import keyword
import pkgutil

app = QtWidgets.QApplication(sys.argv)
editor = Qsci.QsciScintilla()
lexer = Qsci.QsciLexerPython()
editor.setLexer(lexer)

## setup autocompletion
api = Qsci.QsciAPIs(lexer)

for key in keyword.kwlist + dir(__builtins__):
    api.add(key)

for importer, name, ispkg in pkgutil.iter_modules():
    api.add(name)

api.prepare()

editor.setAutoCompletionThreshold(1)
editor.setAutoCompletionSource(Qsci.QsciScintilla.AcsAPIs)

editor.show()
editor.setText(open(sys.argv[0]).read())
sys.exit(app.exec_())
person eyllanesc    schedule 11.10.2017
comment
Благодарю. Не могли бы вы объяснить, какую роль лексер играет в автозаполнении? Кроме того, относительно просто реализовать автозаполнение стандартного библиотечного модуля с функциями из стандартной библиотеки? - person Vince W.; 12.10.2017
comment
Я обновил свой ответ, я добавил функцию знания имен библиотек, но это не умное автозаполнение. Пожалуйста, если мой ответ поможет вам, не забудьте отметить его как правильный. - person eyllanesc; 12.10.2017
comment
ответ в правильном направлении, но имеет некоторые нежелательные последствия. Например, если я установлю источник автозаполнения на AcsAll, чтобы он включал слова документа, а также API, автозаполнение имеет смысл для слов документа. А именно, когда я набираю sys., он предлагает sys.argv и sys.exit, потому что они есть в документе. Когда я набираю range.r, мне будут предложены range.range и range.raise, что явно не имеет смысла. Я не уверен, что автозаполнение, которое иногда предлагает неправильные вещи, - это то, что я ищу. - person Vince W.; 12.10.2017
comment
Я имел в виду, что это не интеллектуальное автозаполнение, вы должны фильтровать данные, которые дает QsciAPI. - person eyllanesc; 12.10.2017