Найти - Пользователи
Полная версия: PyQt4+Python3. Как отследить нажатие на клавишу или комбинацию клавиш?
Начало » GUI » PyQt4+Python3. Как отследить нажатие на клавишу или комбинацию клавиш?
1 2 3
Ginibe
dartNNN, спасибо за науку!
ранее пробовал достать через index.row и index.data, повидимому что-то не так использовал, потому что у меня не получилось, жаль что код ошибочных попыток не сохранил, не пойму где косячил
кста, под ВиндаЗ и без этого фурычит:
import sip
sip.setapi('QVariant', 1)
dartNNN
Ginibe
import sip sip.setapi('QVariant', 1)
У меня python 3.1, PyQt 4.8.2 и по-умолчанию используется вторая версия PyQt Api, где QVariant не создается, отсутствует QString и еще кое-чего по-другому. Поэтому и пришлось переключиться на 1 версию.
4kpt
На Tkinter делается проще - там есть отдельная функция, которая вешается на Bind - именно по ее коду и определяется нажатая клавиша…
Если я правильно понял вопрос…
Ginibe
dartNNN
У меня python 3.1, PyQt 4.8.2 и по-умолчанию используется вторая версия PyQt Api, где QVariant не создается, отсутствует QString и еще кое-чего по-другому. Поэтому и пришлось переключиться на 1 версию.
пробовал на другом компе, исходные:
ось - winXP SP3
питон - 2.7
PyQt - 4.8.3 (спастил из дебагера, переменная модуля кода по имени PYQT_VERSION_STR)

все работает как и на базе с PyQt версии 4.7.1

dartNNN, или Вы имели в виду другое ?


! опять прошу подсказки !
теперь по поводу назанчения хоткеев
как я понял принцип кодирования хоткея к примеру в посте #10:
1 - определяю новый сигнал/событие для представления lv
self.av = QAction(self.lv)
2 - определяю клавишу по нажатии которой должно сработать событие
self.av.setShortcut(Qt.Key_Enter)
3 - назначаю слот в случае реализации события
self.av.triggered.connect(self.selectName)
но этого не достаточно, как я понял…
что еще нужно сделать ?
как то активировать описанный механизм ?
или вообще все плохо в моем танке ? ;)
dartNNN
Ginibe
все работает как и на базе с PyQt версии 4.7.1
тут я сам в легком смятении, видимо дело в версии питона.
Ginibe
3 - назначаю слот в случае реализации события
но этого не достаточно, как я понял…
что еще нужно сделать ?
Посмотри пост #7
1. В конструктор QAction лучше передавать ее имя.
2. QAction нужно добавить к виджету (главному окну)
Для MainWindow
        self.fileMenu = self.menuBar().addMenu(self.tr("&File"))
self.fileMenu.addAction(self.quitAct)
Для Widget
        self.addAction(self.quitAct)
Ginibe
dartNNN
Посмотри пост #7
Я имел в виду код с использованием абстрактной модели и QListView – пост #10.
Там нет кнопок и меню, ведь по списку в виджете представления можно перемещаться и с помощью клавиш Up и Down.
Как задействовать слот selectName с помощью события “клик” на мыши понятно, уже опробовано, а вот как это же сделать по хоткею на клаве, скажем - , при перемещении по списку с помощью клавиш - я пока не разобрался …
dartNNN
Ginibe, кажется у нас с вами недопонимание возникло. В посте номер 7 описано использование QAction и его добавление к главному окну И К ВИДЖЕТУ!
Если так еще не понятно, то вот я вам даже код готовый приведу
class WindowSlctnList(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)

self.quitAct = QtGui.QAction(self.tr("&Quit"), self)
self.quitAct.setShortcut(self.tr("Ctrl+Q"))
self.quitAct.setStatusTip(self.tr("Quit the application"))
self.quitAct.triggered.connect(self.close)

self.addAction(self.quitAct)
Ginibe
dartNNN, повидимому я неправильно задаю вопрос … или не понимаю ответа …
Ваш пример показывает как связать пункт меню “Quit” с сиганлом нажатия хоткея “Ctrl+Q”, а я талдычу про другое … но может нет принципиальной разницы для моего случая

Лучше продемонстрировать что я хочу получить

см. код из поста #10
кстати, dartNNN, Вы же сами его редактировали…

ВАРИАНТ 1
в классе WindowSlctnList переопределил метод keyPressEvent, т.е. добавил следющий код в область вдидимости класса WindowSlctnList:
    def keyPressEvent(self, event):
if event.key() == Qt.Key_Return :
self.selectName(self.lv.currentIndex())
Смущает то что пришлось переопределять закрытый метод keyPressEvent базового класса QWidget. Наверно это не совсем правильно и красиво, хотя и очень коротко.

ВАРИАНТ 2
в классе WindowSlctnList в методе __init__ добавил следющий код:
        # 1 - определяется новое абстрактное событие, типа синал, для представления lv
self.av = QAction(self.lv)
# 2 - назначаем хоткеем [Enter] по нажатию которого событие реализуется
self.av.setShortcut(Qt.Key_Return)
# 3 - назначаем слот в случае реализации события
self.av.triggered.connect(self.selectPress)
# 4 - активация процесса отслеживания события
self.addAction(self.av)
а также пришлось определить новый метод selectPress для класса WindowSlctnList:
    def selectPress (self):
self.selectName(self.lv.currentIndex())
Напрямую слотом selectName воспользоваться не могу т.к. сигнал void triggered ( bool checked = false ) наследуется от QAction, как видим здесь параметром выступает флаг проверки.

2-й вариант конечно избыточен по коду, но при этом не переопределяется защищеная функция

Приложение показывает виджет в виде списка, при клике на мыши в области какого либо пункта списка отрабатывает слот selectName.
Также есть возможность перемещаться по списку с помощью клавиш Up(стрелка вверх) и Down(стрелка вниз) на клавиатуре, т.е. выбирать пункты списка, а также активировать слот selectName нажатием клавиши на выбранном пункте списка.

Не знаю что предпочтительнее, а может есть поинтереснее решение ?
Правильное решение прошу показать в виде кода.
dartNNN
Вариант 1 исключительно правильный в вашем случае. Функция keyPressEvent для того и сделана открытой, чтобы ее можно (и нужно) было переопределять в своих целях. Зациклившись с QAction я просто забыл про такой вариант. Отличие его в том, что для него необходимо писать класс, наследующий QWidget и переопределяющий keyPressEvent. Т.к. он у вас итак есть, то все красиво и непроблемно.

Плюс QAction в том, что он не требует написания отдельного класса, т.е. например можно взять какой-нибудь стандартный виджет и припаять к нему любой action на любую кнопку. И еще кому-то он может показаться читабельнее в случае большого количества кнопок, чем условные ветвления в keyPressEvent
И еще можно писать вот так:
self.av.triggered.connect(lambda: self.selectName(self.lv.currentIndex()))
Ginibe
dartNNN, Вы пишете что фукция keyPressEvent сделана открытой, однако в доке по веруии 4.8 на сайте у nokia эта функция стоит в разделе “Protected Functions”, ну и по традиции вопрос:
что же имеется в виду под “Protected Functions” в контексте Qt ?
Хотя ее переопределение не вызвало конфликтов.

Кста… с lambda конечно же красивее и короче, совсем из головы вылетело… :)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB