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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QTimer  (Прочитано 16016 раз)
QCasper
Гость
« : Декабрь 14, 2005, 01:51 »

запускаю таймер, например так: timer->start(1000); где timer это указатель на объект класса QTimer, как вы впрочем догадались. Значит на событие timeout() таймера, я увеличиваю некую переменную, и ее в лэйбле рисую. Т.е визуально мы видим как тикают секунды. Как только я хватаюсь за окошко, чтобы его потаскать, всякая анимация прекращается. Так вот как сделать, чтобы часы шли, а окошко можно было двигать?
Записан
DenKor
Гость
« Ответ #1 : Декабрь 14, 2005, 11:25 »

Запускать QTimer в отдельной нити
Записан
Hellenna
Гость
« Ответ #2 : Декабрь 14, 2005, 14:40 »

Вызывать в том же цикле, где обновляется лейбл:
Код:

qApp->processEvents();
Записан
QCasper
Гость
« Ответ #3 : Декабрь 14, 2005, 20:22 »

Цитата: "Hellenna"
Вызывать в том же цикле, где обновляется лейбл:
Код:

qApp->processEvents();


у меня не в цикле обновляется, а при сигнале timeout()
Записан
Hellenna
Гость
« Ответ #4 : Декабрь 15, 2005, 11:31 »

Цитата: "QCasper"


у меня не в цикле обновляется, а при сигнале timeout()

ну значит, по сигналу Подмигивающий
смысл в том что этот вызов дает возможность твоему приложению обрабатывать внешние события, такие как переисовка контекста и пр.
Записан
QCasper
Гость
« Ответ #5 : Декабрь 15, 2005, 15:16 »

Цитата: "Hellenna"
Цитата: "QCasper"


у меня не в цикле обновляется, а при сигнале timeout()

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


вот смотри, в конструкторе своего виджета, я соединяю кнопку старт, вернее ее сигнал кликед, с неким this слотом, пусть будет slot1(), в котором происходит timer->start(10); где timer, как я уже говорил, QTimer *timer; вот, в конструкторе, буквально строчкой ниже, я соединяю сигнал timer'a timeout(), со слотом, пусть будет slot2(), в котором я увеличиваю некую переменную, и в лэбле ее показвыаю.
Теперь, будьте любезны, объясните мне где и что я должен поправить?
В том числе, если проблема будет решаться с помощью отдельного потока.
Записан
Dendy
Гость
« Ответ #6 : Декабрь 15, 2005, 19:29 »

QTimer тебе здесь не помощник. Его сигнал timeout() емитится не чаще чем указанньlй интервал таймера. Если на 5 секунд потягать окошко - главньlй поток приостановится, после чего тьl примешь один-единственньlй сигнал, а не столько, сколько их прошло пока не вьlполнялась очередная итерация главного цикла. Как альтернатива QTimer::singleShot( 0, slot ) вьlзовется на следующей итерации главного цикла, то-есть не реже, чем через 0 мс.

Второй поток тоже не помощник. Неглавньlй цикл второго потока точно также может приостанавливаться, в результате чего получишь задержку и не-реальньlй интервал вьlполнения слота.

Единственньl способ посчитать реальное время - заюзать QTime:

Код:
MyWidget::startTimer()
{
  time.start(); // QTime time in declaration
  timer->start( 1000 );
}

void MyWidget::timerSlot()
{
  label->setNum( time.elapsed() );
}


Веселый
Записан
QCasper
Гость
« Ответ #7 : Декабрь 16, 2005, 00:30 »

Dendy, а как сделать чтобы не зимарало обновление при движении окна? Мне грубо говоря секундомер сделать надо.
Записан
Dendy
Гость
« Ответ #8 : Декабрь 16, 2005, 10:30 »

А никак, ьопт... если под виндой...

Драть М$, драть долго кверху задом (с)

Главньlй цикел мрёт пока окно тягается. А так как окна можна создавать ТОЛЬКО в главном цикле, то никакого оповещения работьl сделать не получится. Таймер же при ентом может прекрастно работать в другом потоке.

Если кто знает как избавиться от етого - кричите. Для примера попробуйте потягать окошко копирования файла в проводнике - там всё прекрастно работает.
Записан
ElderOrb
Гость
« Ответ #9 : Декабрь 16, 2005, 10:46 »

Я не проверял, но мне кажется должно работать если сделать так:
Делаем два потока, гуи и воркер. Воркер занимается тем что по прохождению нужных промежутков времени (как это реализовано, через таймер или через тайм или ещё как - не важно) посылает кастом ивент с данными о времени главному потоку. Причем посылает не post-ом, а send-ом. А главный поток по приходу кастом ивента берёт оттуда время и обновляет нужный контрол.
Записан
DenKor
Гость
« Ответ #10 : Декабрь 16, 2005, 11:14 »

Я так и реализую в своих программах работу между потоками.
Обновление окон нормальное
Записан
QCasper
Гость
« Ответ #11 : Декабрь 16, 2005, 11:53 »

Друзья, будьте любезны простейший примерчик, а то ваши слова касты, инвенты, меня как-то немножко напугали, я не знаю что это такое, поэтому, если не трудно, простейший с гуи и ворк потоками примерчик.
Записан
Dendy
Гость
« Ответ #12 : Декабрь 16, 2005, 12:16 »

Всё круто, мужики! Веселый  Теперь покажите мне код. Дело как раз в том, что кастом евент возьмётся когда главньlй поток оживёт (после отпускания мьlши с заголовка окна). Знаю, что ето можно сделать, вопрос как ето сделать в Qt?
Записан
ElderOrb
Гость
« Ответ #13 : Декабрь 16, 2005, 15:30 »

Только что попробовал сделать как я сам написал и обнаружил две любопытных вещи: 1. из одного потока в другой сделать sendEvent не даёт Qt. 2. Если делать postEvent, а в главном потоке при получении любого Event-а делать sendPostedEvents то вроде кастом ивент из другого потока доходит нормально. Проблема в том, что захват заголовка окна мышью не является Event-ом (или я не нашёл каким), а следовательно отфильтровать его и вставить перед его обработкой sendPostedEvents не представляется возможным. Как бы то ни были, в результате я получил хотя бы возможность обновления виджэта при его перемещении ж)))

Код:

#include <QtGui/QApplication>
#include <QLCDNumber>
#include <QThread>
#include <QEvent>
#include <QTime>
#include <QMouseEvent>

enum EventType {
EVENT_UPDATE = QEvent::User + 1
};

class UpdateEvent : public QEvent
{
public:
UpdateEvent(int num) : QEvent((QEvent::Type) EVENT_UPDATE),
number(num) {;}

int number;
};

class UpdateThread : public QThread
{
public:
UpdateThread(QObject* o) : QThread(o), receiver(o) {;}

virtual void run() {

time.start();
while(true) {
UpdateEvent* event = new UpdateEvent(time.elapsed());
QApplication::postEvent(receiver, event);
msleep(1);
}
}

private:
QTime time;
QObject* receiver;
};

class QTestWidget : public QLCDNumber
{
public:
QTestWidget(QLCDNumber* w = NULL) : QLCDNumber(w) {;}
protected:
void mousePressEvent(QMouseEvent* e) {
QApplication::sendPostedEvents(this, EVENT_UPDATE);
}

bool event(QEvent* e) {
if(e->type() == EVENT_UPDATE) {

UpdateEvent* event = (UpdateEvent*) e;
display(event->number);
return true;
} else {
QApplication::sendPostedEvents(this, EVENT_UPDATE);
}

return QLCDNumber::event(e);
}
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTestWidget w;
    w.show();

UpdateThread t(&w);
t.start();

    return a.exec();
}


p.s. Если кто-нибудь сможет отловить событие захвата кэпшена - проблема будет решена полностью.
Записан
QCasper
Гость
« Ответ #14 : Декабрь 16, 2005, 15:52 »

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

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


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