Название: QKeySequenceWidget -- виджет для ввода пользовательских шорткатов
Отправлено: DOOMer от Август 24, 2010, 17:37
В одном из проектов мне потребовалось сделать возможность настройки пользователем шорткатов. Готового решения в интернете не нашлось, кроме как в исходниках KDE -- класс KKeySequenceWidget. На основе последнего мной и был написан виджет qkeySequenceWidget.
Отличие от KDE-прототипа в том что мой виджет не требует KDELibs, а также имеет пару дополнительных свойств для настройки внешнего вида виджета (расположение кнопки сборса заданной qkeySequence + загрузка своей картинки для этой кнопки + задание своей надписи для отражения "неопределенности" QKEySEquence). . (http://qt-apps.org/CONTENT/content-pre1/129224-1.png)
(http://qt-apps.org/CONTENT/content-pre2/129224-2.png)
Виджет написан с использованием _только_ средств qt, никакого платформозависимого кода нет. В связи с этим есть некоторые ограничения (не будут обрабатываться некоторые комбинации клавиш -- например "Alt + PrtScr" ).
Выложил исходники на Qt-Apps (http://qt-apps.org/content/show.php/QKeySequenceWidget?content=129224) (BSD License)
Название: Re: QKeySequenceWidget -- виджет для ввода пользовательских шорткатов
Отправлено: Пантер от Август 24, 2010, 18:05
А для шорткатов аля Емакс оно работает? Т.е. типа Ctrl+X,Ctrl+C.
Название: Re: QKeySequenceWidget -- виджет для ввода пользовательских шорткатов
Отправлено: DOOMer от Август 24, 2010, 18:08
Т.е сначала отлавливаем Ctrl+X, а потом Ctrl+C. и все это сохраняем вместе? Или как? Я Emacs не юзал вообще, больше vim предпочитаю из этих 2 редакторов.
Название: Re: QKeySequenceWidget -- виджет для ввода пользовательских шорткатов
Отправлено: Авварон от Август 24, 2010, 18:15
не вижу смысла тут же задавать иконку...
Название: Re: QKeySequenceWidget -- виджет для ввода пользовательских шорткатов
Отправлено: DOOMer от Август 24, 2010, 18:19
не вижу смысла тут же задавать иконку...
Почему же?
Название: Re: QKeySequenceWidget -- виджет для ввода пользовательских шорткатов
Отправлено: Авварон от Август 24, 2010, 18:24
ну вы же в диалоге выбора цвета не выбираете скин приложения?
Название: Re: QKeySequenceWidget -- виджет для ввода пользовательских шорткатов
Отправлено: DOOMer от Август 24, 2010, 18:29
Ну эта возможность не столько для пользователей, сколько для разработчиков, использующих виджет -- на тот случай, если дефолтная иконка не будет вписываться в общее оформление разработываемой софтины.
А так конечно вы правы, возможность не особо нужная.
Название: Re: QKeySequenceWidget -- виджет для ввода пользовательских шорткатов
Отправлено: Авварон от Август 24, 2010, 18:31
иконка должна задаваться программно, через метод setDefaultIcon или как-то так
Название: Re: QKeySequenceWidget -- виджет для ввода пользовательских шорткатов
Отправлено: Пантер от Август 25, 2010, 06:21
Я когда-то писал вот такую вещь: C++ (Qt) /******************************************************************** * Copyright (C) PanteR *------------------------------------------------------------------- * * Panther Commander is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * Panther Commander is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Panther Commander; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA *------------------------------------------------------------------- * Project: Panther Commander * Author: PanteR * Contact: panter.dsd@gmail.com *******************************************************************/ #ifndef PCSHORTCUTEDIT_H #define PCSHORTCUTEDIT_H #include <QtGui/QLineEdit> class PCShortcutEdit : public QLineEdit { Q_OBJECT public: PCShortcutEdit(QWidget *parent = 0); virtual ~PCShortcutEdit() {} void setShortcut(const QKeySequence& ks); QKeySequence shortcut(); protected: bool event(QEvent *e); private: void handleKeyEvent(QKeyEvent *e); int translateModifiers(Qt::KeyboardModifiers state, const QString &text); private: int m_key[4], m_keyNum; private Q_SLOTS: void textChange(const QString& text); }; #endif // PCSHORTCUTEDIT_H
C++ (Qt) /******************************************************************** * Copyright (C) PanteR *------------------------------------------------------------------- * * Panther Commander is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * Panther Commander is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Panther Commander; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA *------------------------------------------------------------------- * Project: Panther Commander * Author: PanteR * Contact: panter.dsd@gmail.com *******************************************************************/ #include <QtCore/QEvent> #include <QtGui/QKeyEvent> #include "pcshortcutedit.h" PCShortcutEdit::PCShortcutEdit(QWidget *parent) :QLineEdit(parent) { m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0; connect(this, SIGNAL(textChanged(QString)), this, SLOT(textChange(QString))); } bool PCShortcutEdit::event(QEvent *e) { if ( e->type() == QEvent::KeyPress ) { QKeyEvent *k = static_cast<QKeyEvent*>(e); handleKeyEvent(k); return true; } if ( e->type() == QEvent::Shortcut || e->type() == QEvent::ShortcutOverride || e->type() == QEvent::KeyRelease ) return true; return QLineEdit::event(e); } void PCShortcutEdit::handleKeyEvent(QKeyEvent *e) { int nextKey = e->key(); if ( m_keyNum > 3 || nextKey == Qt::Key_Control || nextKey == Qt::Key_Shift || nextKey == Qt::Key_Meta || nextKey == Qt::Key_Alt ) return; nextKey |= translateModifiers(e->modifiers(), e->text()); switch (m_keyNum) { case 0: m_key[0] = nextKey; break; case 1: m_key[1] = nextKey; break; case 2: m_key[2] = nextKey; break; case 3: m_key[3] = nextKey; break; default: break; } m_keyNum++; QKeySequence ks(m_key[0], m_key[1], m_key[2], m_key[3]); setText(ks); e->accept(); } int PCShortcutEdit::translateModifiers(Qt::KeyboardModifiers state, const QString &text) { int result = 0; // The shift modifier only counts when it is not used to type a symbol // that is only reachable using the shift key anyway if ((state & Qt::ShiftModifier) && (text.size() == 0 || !text.at(0).isPrint() || text.at(0).isLetter() || text.at(0).isSpace())) result |= Qt::SHIFT; if (state & Qt::ControlModifier) result |= Qt::CTRL; if (state & Qt::MetaModifier) result |= Qt::META; if (state & Qt::AltModifier) result |= Qt::ALT; return result; } void PCShortcutEdit::setShortcut(const QKeySequence& ks) { m_keyNum = ks.count(); for (int i = 0; i < m_keyNum; ++i) { m_key[i] = ks[i]; } this->setText(ks); } QKeySequence PCShortcutEdit::shortcut() { return QKeySequence::fromString(text()); } void PCShortcutEdit::textChange(const QString& text) { if (text.isEmpty()) m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0; }
Посмотри, может чего полезного увидишь. Кстати, многоуровневые шорткаты у меня поддерживаются. ;)
Название: Re: QKeySequenceWidget -- виджет для ввода пользовательских шорткатов
Отправлено: DOOMer от Август 25, 2010, 11:33
иконка должна задаваться программно, через метод setDefaultIcon или как-то так
Метод для этого есть, просто называется по другому немного (setClearButtonIcon(QIcon &icon)), через него иконку и задаем. Можно было ещё и в дополнительный конструктор вставить загрузку кастомной иконки, но я не стал этого делать. Одна лищняя строчка в "пользовательском" коде погоды не сделает. Посмотри, может чего полезного увидишь. Кстати, многоуровневые шорткаты у меня поддерживаются. ;)
Спасибо :) Видимо я плохо смотрел исходники твоего коммандера, не заметил этот класс. Так может бы и не стал "велосипедить" =) Идею с многоуровневыми шорткатами возьму "на вооружение", может через некоторое время оформлю её в этот виджет.
|