The keyPressEvent does not work
-
The keyPressEvent does not work. for the Tetris class. I'm creating a tetris game, and in order to shuffle the shapes across the screen, I want to use a keyPressEvent, but for some reason, when I set a keyPressEvent for my class, it doesn't work, even the usual trigger log is not output. There is a keyPressEvent on the global window class, but when I define it for my class, it does not work
"Tetris.cpp"
#include "tetris.h"
#include "ui_tetris.h"
#include <QLabel>
#include <QPropertyAnimation>
#include <QMainWindow>
#include <QGridLayout>
#include <QTime>
#include <QVector>
#include <QGroupBox>
#include <QTimer>
#include <QThread>
#include <QKeyEvent>Game::Game(QWidget *parent, QVBoxLayout *layout){
this->parent = parent;
this->layout = layout;
field = createGameField(parent);
field_rect = field->contentsRect();
setupCharacterAppearance();
}void Game::start(){
spawnFigure();
}void Game::keyPressEvent(QKeyEvent* event){
qDebug() <<"KeyPressEvent"<<Qt::endl;
if(event->key() == Qt::Key_Left){
qDebug() <<"sdafadsf"<<Qt::endl;
}
}void Game::setupCharacterAppearance(){
layout->addWidget(field, 0, Qt::AlignCenter);
}QGroupBox* Game::createGameField(QWidget *parent){
QGroupBox *field = new QGroupBox("", parent);
field->setFixedSize(600, 720);
field->setStyleSheet("QGroupBox {border:1px solid black; overflow:hidden}");return field;
}
QLabel* Game::createBlock(const QColor& color){
QLabel *block = new QLabel;
block->setStyleSheet(QString("border:1px solid black; background-color: %1").arg(color.name())); // Используем %1 вместо &1
return block;
}QGroupBox* Game::generateFigureType1 (){
QVector<QLabel*> arrBlocks;
QColor currentColor = arrColors[rand()%4];QGroupBox *figureBox = new QGroupBox("", field); figureBox->setFixedSize(60, 120); figureBox->setStyleSheet("border:none"); QGridLayout *gridLayout = new QGridLayout(figureBox); gridLayout->setSpacing(0); gridLayout->setContentsMargins(0,0,0,0); for(int i=0; i<5;++i){ arrBlocks.push_back(createBlock(currentColor)); } gridLayout->addWidget(arrBlocks[0], 0,0); gridLayout->addWidget(arrBlocks[1], 0,1); gridLayout->addWidget(arrBlocks[2], 1,1); gridLayout->addWidget(arrBlocks[3], 2,1); gridLayout->addWidget(arrBlocks[4], 3,1); return figureBox;
}
void Game::spawnFigure (){
//qDebug()<<"SpawnFigure"<<Qt::endl;
current_figure = generateFigureType1();parent->setFocusPolicy(Qt::StrongFocus); parent->setFocus(); field->setFocusPolicy(Qt::StrongFocus); field->setFocus(); //qDebug()<<"SpawFigure"<<Qt::endl; QVector<int> cords_arr; int x= field_rect.left(); int y = field_rect.top()-1; int field_rectBottom = field_rect.bottom(); for(int i=0; i<18;++i){ cords_arr.push_back(x); x +=30; } current_figure->move(cords_arr[rand()%18],y); motionHandler(field_rectBottom,current_figure);
}
void Game::handleFigureMotion( QGroupBox* current_figure){
current_figure->move(current_figure->x(), current_figure->y()+30);
//qDebug()<<"handleFigureMotion"<<Qt::endl;
}void Game::motionHandler(int field_rectBottom, QGroupBox* current_figure){
QTimer *timer = new QTimer(current_figure);
QAction::connect(timer, &QTimer::timeout, = mutable {
//qDebug()<<"motionHandler"<<Qt::endl;
if(!StopList(field_rectBottom, current_figure)){
//qDebug()<<"motionHandler"<<Qt::endl;
timer->stop();
timer->deleteLater();
return; //выходит из функции если не написать, тогда выполнится еще одно действие ниже
}else{
handleFigureMotion(current_figure);
}
});
timer->start(1000);
}bool Game::StopList(int field_rectBottom, QGroupBox* current_figure){
// qDebug()<<"StopList"<<Qt::endl;
if(current_figure->geometry().bottom() == field_rectBottom+1 ){
return false;
}
return true;
}Tetris::Tetris(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::Tetris)
{
ui->setupUi(this);
QWidget *CentralWidget = new QWidget(this);
setCentralWidget(CentralWidget);
QVBoxLayout *layout = new QVBoxLayout(CentralWidget);Game tetris(CentralWidget, layout); tetris.start(); setFocus();
}
Tetris::~Tetris() {
delete ui;
}"Main.cpp"
#include "tetris.h"#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);srand(time(NULL)); Tetris w; w.show(); return a.exec();
}
"tetris.h"
#ifndef TETRIS_H
#define TETRIS_H#include "qboxlayout.h"
#include "qgroupbox.h"
#include "qlabel.h"
#include <QMainWindow>
#include <QGroupBox>QT_BEGIN_NAMESPACE
namespace Ui {
class Tetris;
}
QT_END_NAMESPACEclass Game: public QWidget {
Q_OBJECT
public:
explicit Game(QWidget* parent, QVBoxLayout* layout );
void start();
protected:
//bool eventFilter(QObject* watched, QEvent* event) override;
void keyPressEvent(QKeyEvent *event) override;
private:
QGroupBox field;
QRect field_rect;
QVBoxLayout layout;
QVector<QColor> arrColors = {
QColor(255, 0,0),
QColor(0, 255, 0),
QColor(0,0,255),
QColor(128,0,128) };
QGroupBox current_figure;
QWidget parent;void handleKeyPress(QKeyEvent *event); void setupCharacterAppearance(); QGroupBox* createGameField(QWidget* parent); QLabel* createBlock(const QColor& color); QGroupBox* generateFigureType1 (); void spawnFigure(); void handleFigureMotion( QGroupBox* current_figure); void motionHandler(int field_rectBottom, QGroupBox* current_figure); bool StopList(int field_rectBottom, QGroupBox* current_figure);
};
class Tetris : public QMainWindow
{
Q_OBJECTpublic:
Tetris(QWidget *parent = nullptr);
~Tetris();private:
Ui::Tetris *ui;
};
#endif // TETRIS_H -
Hi and welcome to devnet,
Your Game object lifetime is one of the key elements. It is destroyed as soon as the method finishes.
On a side note, please use coding tags (the
</>
button in the text editor) otherwise your code is pretty much unreadable. -
I suggest something simpler: check the Tetrix example.
It's a fully explained example that implements what you want to do in details.
-