LINUX.ORG.RU

Отобразить перемещение обектов


0

1

Код такой

#include <QtGui>
class myClass : public QGraphicsScene
{
public :
        myClass(QObject *parent = 0);
        virtual void keyPressEvent(QKeyEvent *event);

private :
        QGraphicsEllipseItem *item;
};
myClass::myClass(QObject *parent)
        : QGraphicsScene(parent)
{
        this->setSceneRect(0,0,600,600);
        item = new QGraphicsEllipseItem(0, this);
        item->setRect(QRectF(50,50,100,100));
}
void myClass::keyPressEvent(QKeyEvent *event)
{
        for(int i = 0; i < 200; i++) {
                qDebug() << i;
                item->setPos(i, item->y());
                sleep(1);
        }
}
int main(int argc, char **argv)
{
        QApplication app(argc,argv);
        myClass m;
        QGraphicsView v(&m);
        v.setRenderHints( QPainter::Antialiasing );
        v.show();

        return app.exec();
}
По идее если нажму на кнопку то элипс должен начать медленно двигаться. А в реальной жизни программа ждет эти 200 секунд и моментально перемещает эллипс в конечную точку. Что не так с кодом? Как показать перемещение по человечески??

Ответ на: комментарий от mi_estas

ой, это работать не будет, недосмотрел что там у тебя. точно кури qtimer

mi_estas ()
Ответ на: комментарий от Begemoth

>А документацию для кого писали?

Документацию прочел. Как я понял каждый раз по истечении времени в таймере управление должно передаваться слоту, но похоже этого не происходит

код такой

main.cpp

#include "myClass.h"
int main(int argc, char **argv)
{
        QApplication app(argc,argv);
        myClass m;
        QGraphicsView v(&m);
        v.setRenderHints( QPainter::Antialiasing );
        v.show();

        return app.exec();
}

myClass.h

#ifndef MCL_H
#define MCL_H
#include <QtGui>
#include <QTimer>
        
class myClass : public QGraphicsScene
{       
        Q_OBJECT
        public :
                myClass(QObject *parent = 0);
                virtual void keyPressEvent(QKeyEvent *event);

        private :
                QTimer *timer;
                QGraphicsEllipseItem *item;
        public slots : 
                void upd();
};
#endif // MCL_H

myClass.cpp

#include "myClass.h"

myClass::myClass(QObject *parent)
: QGraphicsScene(parent)
{
        this->setSceneRect(0,0,600,600);
        item = new QGraphicsEllipseItem(0, this);
        item->setRect(QRectF(50,50,100,100));
        timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(upd()));
}               

void myClass::keyPressEvent(QKeyEvent *event)
{               
        timer->start(10);
        for(int i = 0; i < 200; i++) {
                qDebug() << i;
                item->setPos(i, item->y());
                sleep(1);
        }
}
В чем ошибка? Почему не работает?

gDendy ()

Есть же стандартный пример с человечком, почему бы не посмотреть, как это делается идеологичеси правильно в Qt?

unC0Rr ★★★★★ ()
Ответ на: комментарий от gDendy

В чем ошибка? Почему не работает?

Ты вообще пытаешься думать что твой код делает?

Begemoth ★★★★★ ()
Ответ на: комментарий от gDendy

В чем ошибка? Почему не работает?

Я даже не знаю как это корректнее объяснить. Вот этот весь код не нужен в keyPressEvent:

        for(int i = 0; i < 200; i++) {
                qDebug() << i;
                item->setPos(i, item->y());
                sleep(1); // забудь про существование этой функции
        }
Двигать (item->setPos) нужно по таймеру, то есть setPos надо бы куда-нибудь в upd() запихать, от цикла избавиться разумеется.

rival ★★ ()
Ответ на: комментарий от rival

А вообще быть может лучше будет QML под твою задачу заюзать?

Ему надо мозги заюзать, всего-то.

Begemoth ★★★★★ ()
Ответ на: комментарий от gDendy

И кстати код, который ты привёл, не скомпонуется.

Begemoth ★★★★★ ()
Ответ на: комментарий от gDendy

> спасибо, понял)

Действительно, заюзай мозг. А вообще, почитай чужой код (примеры в документации, исходники игр), куда полезнее, чем тыкаться вслепую и спрашивать на лоре про каждую мелочь.

Но если уж тыкаться вслепую, то удобнее тыкаться в динамических языках, потому я и предложил QML.

rival ★★ ()

[Ликбез]

Приложения с графическим интерфейсом пользователя являются однопоточными. Это означает, что весь код, связанный с обслуживанием графического интерфейса выполняется в одном потоке.

Из этого следует, что если в обработчике события начать выполнять длительные (по времени) операции, то на время выполнения таких операций весь графический интерфейс будет «заморожен» до тех пор, пока обработчик не закончит свою работу.

Решить задачу можно двумя путями:

1. Использовать таймер.

Подводных камней мало, но реализовывать сложную логику не всегда удобно. Мало накладных расходов.

2. Создать ещё один поток и в нем обсчитывать длительную операцию.

Писать легко, но надо правильно организовать взаимодействие с основным потоком, где обслуживается графический интерфейс. Лишние накладные расходы на поток.

//Я бы посоветовал делать через таймер.

pathfinder ★★★ ()
Ответ на: [Ликбез] от pathfinder

>Писать легко, но надо правильно организовать взаимодействие с основным потоком, где обслуживается графический интерфейс. Лишние накладные расходы на поток.
хех, в андроиде это из коробки)
надо себе такое-же завелосипедить в кутешный проект

TERRANZ ★★★★ ()
Ответ на: комментарий от TERRANZ

хех, в андроиде это из коробки)

надо себе такое-же завелосипедить в кутешный проект

В Qt тоже почти «из коробки». Все делается очень легко через механизм slot/signal. Легче, чем в Qt я не видел нигде. И не представляю как можно сделать ещё проще.

pathfinder ★★★ ()
Ответ на: комментарий от TERRANZ

я не помню, в кутях система signal -> slot потокобезопасна?

Ага, если сигнал и слот в одном потоке, то все делается через прямой вызов процедуры. Если в разных, то через event_loop.

см. раздел «Signals and Slots Across Threads» тут

pathfinder ★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.