Signals and slots



  • I'm making a tetris game using c++ and QT so far i've managed to get a cube on my board game, and i got it moving up and down.

    now i want to put a timer using signal's and slot's to make the cube drop down every xy seconds.

    i made a move() function in myRect which should do the trick in moving the cube down.
    i tried connecting it with different kind of aproaches, but everytime it failed, so im missing something apparently and cant figure out what.

    i've checked tutorials ofcourse, but most of them are connecting it in main, and i'm under the impression i should be avoiding that type of coding if im to follow OOP- principels.

    Correct me if im wrong, and feel free to comment my code also if you think/see some misuse.

    this is my main

    @int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    novi_pocetak w;

    w.setWindowTitle("Tetris");
    w.show();
    
    return a.exec();
    

    }@

    my widget.h

    @class novi_pocetak : public QWidget
    {
    Q_OBJECT

    public:
    novi_pocetak(QWidget *parent = 0);
    ~novi_pocetak();

    private:
    Ui::novi_pocetakClass ui;
    QGraphicsScene * scene;
    myRect* test;
    QTimer *timer;

    };@

    my widget.cpp

    @novi_pocetak::novi_pocetak(QWidget *parent)
    : QWidget(parent)
    {
    ui.setupUi(this);
    QGraphicsScene * scene = new QGraphicsScene(0,0,310,420);
    myRect * test = new myRect;

    scene->setBackgroundBrush(Qt::black);
    test->setPos(ui.tetrisGV->width()/2,0);
    scene->addItem(test);
    ui.tetrisGV->setScene(scene);
    test->setFocus();
    

    @

    myRect.h

    @class myRect :
    public QGraphicsItem
    {
    public:
    myRect(QGraphicsItem * parent = NULL);
    ~myRect();

    protected :
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    QRectF boundingRect() const;

    virtual void keyPressEvent(QKeyEvent *event);
    void checkBounds();
    void rotate(myRect* rect);
    void move();
    

    };@

    and myRect.cpp

    @myRect::myRect(QGraphicsItem* parent) : QGraphicsItem(parent)
    {
    setFlag(QGraphicsItem::ItemIsFocusable);
    }
    void myRect::move()
    {
    setPos(x(),y()+10);
    update();
    }
    void myRect::keyPressEvent(QKeyEvent *event)
    {
    switch(event->key() )
    {
    case Qt::Key_Right:
    {
    setPos(x()+10,y());
    checkBounds();
    break;
    }
    case Qt::Key_Left:
    {
    setPos(x()-10,y());
    checkBounds();
    break;
    }
    case Qt::Key_Up: {
    setPos(x(),y()-10);
    checkBounds();
    break;
    }
    case Qt::Key_Down: {
    setPos(x(),y()+10);
    checkBounds();
    break;
    }
    }
    update();
    }@

    thx in advance


  • Moderators

    Hi and welcome to devnet

    You are missing to declare your move method as a slot routine.

    @
    class myRect :
    public QGraphicsItem
    {
    public:
    myRect(QGraphicsItem * parent = NULL);
    ~myRect();

    protected :
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    QRectF boundingRect() const;

    virtual void keyPressEvent(QKeyEvent *event);
    void checkBounds();
    void rotate(myRect* rect);
    

    public slots:
    void move();
    };
    @

    and probably you plan something similar to:
    @
    novi_pocetak::novi_pocetak(QWidget *parent)
    : QWidget(parent)
    {
    ui.setupUi(this);
    QGraphicsScene * scene = new QGraphicsScene(0,0,310,420);
    myRect * test = new myRect;

    timer = new QTimer; 
    
    bool boo = connect( timer, SIGNAL ( timeout() ), test, SLOT ( move() ) );
    assert ( boo );
    
    scene->setBackgroundBrush(Qt::black);
    test->setPos(ui.tetrisGV->width()/2,0);
    scene->addItem(test);
    ui.tetrisGV->setScene(scene);
    test->setFocus();
    

    @

    Note: Those are the missing things I see immediately. Please check further.
    I am typically checking the return value of a connect as here with an assert. That is not absolutely necessary, but I find it convenient.
    This needs an include of cassert in the module.



  • Hey there,

    i did as you suggested but i still cant connect it all.

    when i do a

    @timer = new QTimer();
    connect(timer, SIGNAL(timeout()),test,SLOT(move()));
    timer->start(50);@

    i get and error saying i dont have a instance of overloaded function that matches the argument list.
    i have a feeling im missing something rather "stupid" here to get it working.

    @timer->connect(SIGNAL(timeout()),test,SLOT(move()));
    timer->connect(timer,SIGNAL(timeout()),test,SLOT(move()));@

    neither of these will work either, same error.


  • Moderators

    Typically it does state what is missing. Either the signals is not found or the slot method.
    Did you add the "public slots:" in your header and did you do a rebuild?


  • Moderators

    Sorry, probably you need to rerun qmake too.



  • error C2664: 'QMetaObject::Connection QObject::connect(const QObject *,const char *,const QObject *,const char *,Qt::ConnectionType)' : cannot convert parameter 3 from 'myRect *' to 'const QObject *'

    this is the error msg.



  • i also didn't mention im doing this in VS2010, with the addin. not sure if its relevant


  • Moderators

    Sorry my fault.
    There is more missing. You need to include the Q_OBJECT macro.

    @
    class myRect :
    public QGraphicsItem
    {
    Q_OBJECT
    @



  • i tried that, didnt work either.
    when i do the macro t i get

    GeneratedFiles\Debug\moc_myRect.cpp(65): error C2440: 'static_cast' : cannot convert from 'QObject *' to 'myRect *'

    GeneratedFiles\Debug\moc_myRect.cpp(75): error C2039: 'staticMetaObject' : is not a member of 'QGraphicsItem'

    GeneratedFiles\Debug\moc_myRect.cpp(82): error C2227: left of '-metaObject' must point to class/struct/union/generic type

    GeneratedFiles\Debug\moc_myRect.cpp(82): error C2227: left of '-dynamicMetaObject' must point to class/struct/union/generic type

    GeneratedFiles\Debug\moc_myRect.cpp(90): error C2039: 'qt_metacast' : is not a member of 'QGraphicsItem'

    and the previus error stays, still cant convert it.

    is it maybe a problem that my class derives from QGraphicsItem?


  • Moderators

    The macro makes sure that "moc" is started.
    You need to have "moc" started and that is giving you the trouble.

    Can you work with one the examples?
    I am not sure if it is something with your setup. Therefore, please checkout one the examples and compile and try it out.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.