Russian Qt Forum
Ноябрь 24, 2024, 19:07 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Q<control>View и key events  (Прочитано 6408 раз)
SABROG
Гость
« : Июль 26, 2007, 16:49 »

Ситуация, как обычно, сложная. Т.к. интерфейс я рисую в дизайнере, то в моей программе нет ни одного унаследованного контрола, который бы я создавал ручками и лепил в нужное место на форму. С сигналами все более-менее понятно, а вот как обработать нажатие клавиш в QTreeView, скажем кнопку Del и удалить выбранный элемент ? Мышка это рулез форева, но иногда приходится обкликиваться, пока доберешься до нужного пункта меню... Неужели без InstallEvent фильтра не обойтись ?

Сейчас это реализовано так:

Код:

eventHooker::eventHooker(TForm *parent) : QObject(parent)
{
main = parent;
}
bool eventHooker::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
    if (obj->objectName() == "tvTemplate")
    {
            if (keyEvent->key() == Qt::Key_Delete)
            {
            main->deleteTemplate();
            return true;
            }    
    }
        return false;
    }
    else
    {
    return QObject::eventFilter(obj, event);
    }
}
Записан
-=s0L=-
Гость
« Ответ #1 : Июль 26, 2007, 18:15 »

Цитата: "SABROG"
Ситуация, как обычно, сложная. Т.к. интерфейс я рисую в дизайнере, то в моей программе нет ни одного унаследованного контрола, который бы я создавал ручками и лепил в нужное место на форму. С сигналами все более-менее понятно, а вот как обработать нажатие клавиш в QTreeView, скажем кнопку Del и удалить выбранный элемент ? Мышка это рулез форева, но иногда приходится обкликиваться, пока доберешься до нужного пункта меню... Неужели без InstallEvent фильтра не обойтись ?

Сейчас это реализовано так:

Код:

eventHooker::eventHooker(TForm *parent) : QObject(parent)
{
main = parent;
}
bool eventHooker::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
    if (obj->objectName() == "tvTemplate")
    {
            if (keyEvent->key() == Qt::Key_Delete)
            {
            main->deleteTemplate();
            return true;
            }    
    }
        return false;
    }
    else
    {
    return QObject::eventFilter(obj, event);
    }
}


врятли можно по другому, на сообщения клавиатуры qt генерирует  события, а сигналы это уже выше уровнем, они для других целей.
Записан
vaprele07
Гость
« Ответ #2 : Июль 27, 2007, 00:58 »

В дизайнере начиная с версии qt 4.3~ появилась фишка promote to, бросаешь на форму свой QTreeView, делаешь ему промоут от MyTreeView. Все просто и без заморочек.

и уже пользуешься сигналами а не слотами:

Код:

void keyPressEvent(QKeyEvent *e)
{
  QTreeView::keyPressEvent(e);
  emit onKeyPressed(e);
}
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #3 : Июль 27, 2007, 05:46 »

Ну во первых это не в 4.3 появилось, а раньше...
А во вторых, все равно придется наследоваться - делать класс MyTreeView.
В третьих, а зачем тут emit?  :roll:
По моему надо что то типа QWidget::keyPressEvent(ke) вызвать в конце...
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
vaprele07
Гость
« Ответ #4 : Июль 27, 2007, 07:53 »

Racheengel ну а что лучше использовать евэнт фильтр или готовый про виджет, промоут для того и был создан чтобы мы не парились с ручной подгонкой.
emit на случай если где-то у потомков забудется Q_OBJECT, компилятор игнорирует данную строку, она генерируется только при мок проходе.
Код:

class MyTreeView : public QTreeView
{
  Q_OBJECT
  public:  
    MyTreeView(QWidget *parent = 0)
      : QTreeView(parent) { /** */ }
    virtual ~MyTreeView() { /** */ }
  protected:
    void keyPressEvent(QKeyEvent *event)
    {
      event->ignore();
      emit onKeyPressed(event);
      if (!event->isAccepted()) QTreeView::keyPressEvent(event);
    }
  public slots:
    void currentChanged(const QModelIndex &current, const QModelIndex &previous)
    {
       emit onChanged(current, previous);
    }
  signals:
    void onKeyPressed(QKeyEvent *event);
    void onChanged(const QModelIndex &index, const QModelIndex &previous);
};
Записан
SABROG
Гость
« Ответ #5 : Июль 27, 2007, 08:05 »

Спасиб, а можешь пояснить логику класса. Не могу вкурить для чего ignore, accepted и ручная отправка сигналов.
Записан
vaprele07
Гость
« Ответ #6 : Июль 27, 2007, 08:22 »

SABROG если тебе вдруг приспичить забанить логику обработки клавиши, допустим F2, ты в onKeyPressed делаешь event->accept();
Записан
bigirbis
Гость
« Ответ #7 : Июль 27, 2007, 12:09 »

Я такую задачу с помощью QShortcut решал...
Записан
SABROG
Гость
« Ответ #8 : Июль 27, 2007, 13:04 »

В принципе так работает, только есть проблема, шорткут, он и в африке шорткут, а значит работает независимо от фокуса окна, даже если я выбрал итем в другом QTreeView:

Код:

connect(new QShortcut(QKeySequence(Qt::Key_Insert), tvTemplate),SIGNAL(activated()),this,SLOT(newTemplate()));
Записан
bigirbis
Гость
« Ответ #9 : Июль 27, 2007, 13:55 »

Цитировать
В принципе так работает, только есть проблема, шорткут, он и в африке шорткут, а значит работает независимо от фокуса окна, даже если я выбрал итем в другом QTreeView

Попробуй так:
Код:
new QShortcut( Qt::Key_Insert, tvTemplate, SLOT( newTemplate() ), 0, Qt::WidgetShortcut );
Записан
SABROG
Гость
« Ответ #10 : Июль 27, 2007, 18:48 »

Цитата: "bigirbis"
Цитировать
В принципе так работает, только есть проблема, шорткут, он и в африке шорткут, а значит работает независимо от фокуса окна, даже если я выбрал итем в другом QTreeView

Попробуй так:
Код:
new QShortcut( Qt::Key_Insert, tvTemplate, SLOT( newTemplate() ), 0, Qt::WidgetShortcut );


Так не работает. А так работает:

Код:

connect(new QShortcut(Qt::Key_Insert, tvTemplate, 0, 0, Qt::WidgetShortcut),SIGNAL(activated()),this,SLOT(newTemplate()));


Вопрос про promote есть, там надо указывать header - .h файл, он должен сам создаваться или я его должен каким-то специальным образом оформить ?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.05 секунд. Запросов: 23.