Есть объект QTimer, связан со слотом, но почему-то после start в этот слот не заходит, хотя время идёт. В чем может быть проблема?
class object: public QDialog
{
Q_OBJECT
QTimer* Timer;
void func();
public slots:
void update();
};
1) где и как создаёшь объект QTimer?
2) где соединяешь сигнал и слот ?
3) где вызываешь start ?
4) как определяешь, что "время идёт"?
class object: public QDialog
{
Q_OBJECT
QTimer* Timer;
void func();
public slots:
void update();
};
class object: public QDialog
{
Q_OBJECT
QPushButton* Button;
QTimer* Timer;
void func();
public slots:
void update();
};
object::object ()
{
Button = new QPushButton(this);
Timer = new QTimer (this);
connect(Button, SIGNAL(clicked(bool)), this, SLOT(func()));
connect(Timer, SIGNAL(timeout()), this, SLOT(update ()));
}
void object::func()
{
Timer->start(100);
//bla-bla-bla
Timer->stop();
}
void object::update();
{
//bla-bla-bla
}
а как он обработается, если ты его тут же остановил ?
Алексей1153, я неверно не очень понимаю суть объекта QTimer. В чем проблема, что я его остановил потом? В промежуток между стартом и стопом выполяняется затратный по времени код.
Ov3r1oad, у тебя однопоточное приложение. Пока ты не вышел из функции func у тебя ни одно сообщение системы не обработается без специальных приёмов.
Расскажи задачу
Алексей1153, ну в общем, я уже по сути все рассказал =). Вот мне нужно, чтобы каждую 0.1 секунду для кода, который между стартом и стопом, вызывалась функция (в которой меняется уровень ProgressBar). Все равно для меня не очень понятен механизм работы QTimer. Получается, я должен вызвать start и stop в разных функциях?
Ov3r1oad,
нужно или выпрямить рученки, или грамотно запостить свой код.
А по теме: а я не вижу (ну никак) слота
SLOT(func())
kuzulis, да это опечатка, слот это, слот. Я просто даже не вижу, как здесь отредактировать сообщение.
А может пускай таймер постоянно квакает, но в слоте update() смотреть на какой-то внешний флаг активности, который поднимается в object::func() ?
Ov3r1oad Функция stop() останавливает ваш таймер. Если вы ее вызываете сразу после start() то ваш таймер даже одного раза не успевает отработать.
В функции func() нужно вызвать только start(). А stop() нужно вызвать только после того как ваш таймер выполнит то что ему полагается. В вашем случае это достижение ProgressBar уровня 100%. Значит вам следует либо в функции update() проверять уровень ProgressBar или извне вызвать функцию stop() когда уровень ProgressBar достигнет 100%.
ilyabvt, Так в функции update() и меняется ProgressBar =), а в этот update, собственно и не заходит вообще программа. Тут видимо надо вызывать поток отдельный для этого таймера.
Ov3r1oad Конечно не заходит, ведь вы его остановили. Уберите функцию stop() из func() и поместите ее в update().
Ov3r1oad,
class object: public QDialog
{
Q_OBJECT
QTimer* timer;
QPushButton* button_timer_start;
QPushButton* button_timer_stop;
private slots:
void slot_obj_update();
void slot_timer_start();
void slot_timer_stop();
};
object::object ()
{
timer = new QTimer(this);
button_timer_start = new QPushButton(this);
button_timer_stop = new QPushButton(this);
connect(timer, SIGNAL(timeout()), this, SLOT(slot_obj_update()));
connect(button_timer_start, SIGNAL(clicked()),
this, SLOT(slot_timer_start()));
connect(button_timer_stop, SIGNAL(clicked()),
this, SLOT(slot_timer_stop()));
}
void object::slot_timer_start()
{
timer->start(100);
}
void object::slot_timer_stop()
{
timer->stop();
}
void object::slot_obj_update()
{
//при очередном шаге (срабатывании) таймера попадаете сюда,
//выполняете здесь свои вычисления для этого очередного шага:
//...
//соответственно этому шагу меняете уровень ProgressBar:
//...
}
class object: public QDialog
{
Q_OBJECT
QTimer* timer;
QPushButton* button_timer_start;
private slots:
void slot_obj_update();
void slot_timer_start();
};
object::object ()
{
timer = new QTimer(this);
button_timer_start = new QPushButton(this);
connect(timer, SIGNAL(timeout()), this, SLOT(slot_obj_update()));
connect(button_timer_start, SIGNAL(clicked()),
this, SLOT(slot_timer_start()));
}
void object::slot_timer_start()
{
timer->start(100);
}
void object::slot_obj_update()
{
//при очередном шаге (срабатывании) таймера попадаете сюда,
//выполняете здесь свои вычисления для этого очередного шага:
//...
//соответственно этому шагу меняете уровень ProgressBar:
//...
if (решили, что пора выключить таймер)
timer->stop();
}
Steklova Olga, ilyabvt, В общем, есть вот большой класс, наследуемый от QDialog. В нём куча кнопок, виджетов и прочей требухи. Так же там есть функция, ну допустим, сжатия файлов. Она, эта функция, затратная по времени, и мне нужно, чтобы пользователь понимал, что вот идёт архивация, и приложение не зависло (как ему может показаться). Для этого я хочу, чтобы на ProgressBar шкала просто двигалась назад и вперед, пока идёт архивация. То он нажимает на кнопку "Архивация", в слоте для этой кнопки лежит вот эта функция архивации. Что мне нужно сделать, чтобы прогрессбар у меня обновлялся?
Ov3r1oad, тебе нужно запустить процесс сжатия в отдельном потоке, тогда диалог не перестанет реагировать на сообщения от системы
Алексей1153, а в Qt нет чего-нибудь типа дельфийского Application.ProcessMessages ?
Steklova Olga, это не дельфийское, это виндоапишное ) В таких случаях городится костыль - локальная петля обработки сообщений. Но костыль - он и есть костыль , лучше через поток ИМХО. В Qt я не заморачивался поиском такого подпинывателя, а сейчас глянул - нашёл только для перерисовки, для остальных сообщений не нашёл
И - если сделать по-виндошному, то не будет кроссплатформенности
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)