crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> QGraphicsView + KeyPress Event
Гость_DerKetzer_*
сообщение 6.11.2011, 22:44
Сообщение #1





Гости








    


Доброго времени суток,
Решил поделать курсач. Для этого выбрал библиотеку QT(раньше с ней дело не имел)...
Пытаюсь создать небольшую игрушку. Для этого использую QPainter + QGraphicsView + QGraphicsScene. Как рисовать я понял... Но как считывать нажатие клавиш?

Код main'a:

int main(int argc, char **argv)
{
     QApplication app(argc, argv);
     qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
     QGraphicsScene scene;
     QGraphicsView view;
     for (int i = 0; i < 8; ++i) {
     Tanks *tank= new Tanks;
     scene.addItem(tank);
     }
     view.show();
     return app.exec();
}


Если вставить функцию:

void QGraphicsView::KeyPressEvent(QKeyEvent* event){
    if(event->key()==Qt::Key_W) {
         //Do Smth
    }
}


То при нажатии на 'W' ничего не происходит.

Помогите нубасу пожалуйста! :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
wiz29
  опции профиля:
сообщение 7.11.2011, 12:08
Сообщение #2


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


обрисую в общих чертах, как сделать правильно для твоей программы.
Создай класс который будет генерить сигналы нажатия/отжатия кнопок.
Для это в конструкторе класса установи
    if (qApp)
    {
        qApp->installEventFilter(this);
    }


далее в процедуре фильтра событий обрабатывай QEvent::KeyPress и генери сигнал.
выглядеть это будет примерно следующим образом
bool AppKeyHook::eventFilter(QObject* pObj, QEvent* e)
{
    if (pObj)
    {
        if (e->type() == QEvent::KeyPress)
        {
            QKeyEvent* pKeyEv = static_cast<QKeyEvent*>(e);
            if (!pKeyEv->isAutoRepeat())
            {
                std::map<int, bool>::iterator pos = m_keyMap.find(pKeyEv->key());
                if (pos != m_keyMap.end())
                {
                    if (pos->second == false)
                    {
                        pos->second = true;
                        emit KeyPressed(pKeyEv->key());
                    }
                }
                else
                {
                    m_keyMap[pKeyEv->key()] = true;
                    emit KeyPressed(pKeyEv->key());
                }
            }
        }
        else if (e->type() == QEvent::KeyRelease)
        {
            QKeyEvent* pKeyEv = static_cast<QKeyEvent*>(e);            
            if (!pKeyEv->isAutoRepeat())
            {
                std::map<int, bool>::iterator pos = m_keyMap.find(pKeyEv->key());
                if (pos != m_keyMap.end())
                {
                    if (pos->second == true)
                    {
                        pos->second = false;
                        emit KeyReleased(pKeyEv->key());
                    }
                }
                else
                {
                    m_keyMap[pKeyEv->key()] = false;
                    emit KeyReleased(pKeyEv->key());
                }
            }
        }
    }
    return false;
}

все довольно просто
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_DerKetzer_*
сообщение 7.11.2011, 13:59
Сообщение #3





Гости








    


Спасибо за скорый ответ.
Такс, создал класс(мб что то не правильно понял):
#include <QGraphicsView>
#include <QObject>

class keyPress
{
public:
    keyPress();
    bool eventFilter(QObject* obj, QEvent* e);
protected:
    void KeyReleased(QKeyEvent* e);
    void KeyPressed(QKeyEvent* e);
    QObject* pObj;
private:
    std::map<int, bool> m_keyMap;
};


реализация:

#include <QMessageBox>
#include <QtCore>
#include <QtGui>

keyPress::keyPress()
{
    if(qApp) qApp->installEventFilter (this);
}

void keyPress::KeyReleased(QKeyEvent* e)
{
    QMessageBox msgBox;
    if(e->key ()==Qt::Key_W) msgBox.setText("bla.");

}

void keyPress::KeyPressed(QKeyEvent* e)
{
    QMessageBox msgBox;
    if(e->key ()==Qt::Key_Z) msgBox.setText("The document has been modified.");
}

bool keyPress::eventFilter(QObject* pObj, QEvent* e)
{
...
}

int main(int argc, char **argv)
{
     QApplication app(argc, argv);
     qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
     QGraphicsScene scene;
     QGraphicsView view(&scene);
     keyPress key;
     for (int i = 0; i < 8; ++i) {
         Tanks *tank= new Tanks;
         scene.addItem(tank);
     }
     view.show();
     return app.exec();
}


Наследником чего должен быть класс keyPress? Я так понял, что QGraphicsView... так ли это?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
wiz29
  опции профиля:
сообщение 9.11.2011, 8:27
Сообщение #4


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


Цитата(DerKetzer @ 7.11.2011, 14:59) *
Наследником чего должен быть класс keyPress? Я так понял, что QGraphicsView... так ли это?


Достаточно унаследоваться от QObject
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_DerKetzer_*
сообщение 13.11.2011, 5:47
Сообщение #5





Гости








    


Цитата(wiz29 @ 9.11.2011, 8:27) *
Цитата(DerKetzer @ 7.11.2011, 14:59) *
Наследником чего должен быть класс keyPress? Я так понял, что QGraphicsView... так ли это?


Достаточно унаследоваться от QObject


Спасибо, разобрался)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 25.1.2012, 9:59
Сообщение #6





Гости








    


Вопрос почти в тему:
Как подписаться на таймер?

Имеется ввиду, в таких же условиях работы с QGraphicsScene, ну и новичка, в качестве автора.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 25.1.2012, 12:49
Сообщение #7


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(processOneThing()));
timer->start();
где processOneThing твоя функция член класса, которая вызывается каждый раз, когда происходит событие таймера...

Смотри: QTimer - Подробное описание
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 2.12.2024, 13:50