Решено: qt4 "сброс буфера" [решено] (или как подружить со sleep)
Модератор: Модераторы разделов
-
- Сообщения: 2579
Решено: qt4 "сброс буфера" [решено]
Есть задачка такая. Раз в секунду менять значение какого-то объекта. Например, это ползунок, его нужно каждую секунду куда-то сдвигать, влево или вправо...
Как сдвигать вообще, я разобрался. Создал цикл while. В него вписал команды, которые собственно управляют свойствами, и sleep(1).
Так вот, это всё не работает. Причём программа ещё и намертно зависает при этом. Но не насовсем. А на общее количество секунд простаивания. То есть если цикл while выполнялся 10 раз, то и "спать" программа будет 10 секунд. И потом ползунок сразу сдвинется куда надо за все 10 шагов за один момент (а не пошагово, по одному движению в секунду). А мне надо чтобы он постепенно двигался, плавно.
Провёл эксперимент. Создал консольную программу, которая выводит случайные значения на экран и опять же использует sleep. Если просто после каждого вывода значения вписать функцию sleep(1) - такой же эффект, как в предыдущей задаче. Пишет всё и сразу - но при самом завершении программы.
Если же "поправить" вывод программы, добавив std::flush после каждого std::cout, то выводится нормально, как надо. Потому что сбрасываетя буфер.
В общем, вопрос такой, как сбросить такой же буфер в qt4? Что нужно написать, чтобы все изменения, которые я произвёл со значениями, применились?
Как сдвигать вообще, я разобрался. Создал цикл while. В него вписал команды, которые собственно управляют свойствами, и sleep(1).
Так вот, это всё не работает. Причём программа ещё и намертно зависает при этом. Но не насовсем. А на общее количество секунд простаивания. То есть если цикл while выполнялся 10 раз, то и "спать" программа будет 10 секунд. И потом ползунок сразу сдвинется куда надо за все 10 шагов за один момент (а не пошагово, по одному движению в секунду). А мне надо чтобы он постепенно двигался, плавно.
Провёл эксперимент. Создал консольную программу, которая выводит случайные значения на экран и опять же использует sleep. Если просто после каждого вывода значения вписать функцию sleep(1) - такой же эффект, как в предыдущей задаче. Пишет всё и сразу - но при самом завершении программы.
Если же "поправить" вывод программы, добавив std::flush после каждого std::cout, то выводится нормально, как надо. Потому что сбрасываетя буфер.
В общем, вопрос такой, как сбросить такой же буфер в qt4? Что нужно написать, чтобы все изменения, которые я произвёл со значениями, применились?
-
- Сообщения: 283
- ОС: Debian
Re: Решено: qt4 "сброс буфера" [решено]
Забудьте про sleep. Используйте таймер.
remote system type is unix
Спасибо сказали:
-
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Решено: qt4 "сброс буфера" [решено]
Использовать sleep в основном потоке графического приложения нельзя - вы останавливаете разбор очереди событий и программа "зависает". Как уже говорилось, используйте QTimer.
Спасибо сказали:
-
- Сообщения: 2579
Re: Решено: qt4 "сброс буфера" [решено]
Ммм, я так и думал. Спасибо, что разъяснили.
А можно ли прикрутить qtimer через qt desighner? А то всю форму через него делал... там и компоновать довольно удобно. А то не нашёл такого компонента на палитрах... Помню, в дельфи был такой компонент timer - он именно так и прицеплялся. А тут, видимо, по-другому.
А можно ли прикрутить qtimer через qt desighner? А то всю форму через него делал... там и компоновать довольно удобно. А то не нашёл такого компонента на палитрах... Помню, в дельфи был такой компонент timer - он именно так и прицеплялся. А тут, видимо, по-другому.
-
- Сообщения: 2579
Re: Решено: qt4 "сброс буфера" [решено]
Ладно, с этим может всё равно потом разберусь... Сейчас разобраться, как вообще таймером пользоваться. Где там функция засыпания?
Мне просто надо выполнить одну и ту же операцию неизвестное количество раз, пока не выполнится какое-то условие. То бишь цикл while.
Я так понял, есть функция interval, принимающая в качестве аргумента любую другую функцию, которая и выполняется.. Но мне не это нужно, ведь тогда программа будет выполняться вечно? Или нет? %)
Мне просто надо выполнить одну и ту же операцию неизвестное количество раз, пока не выполнится какое-то условие. То бишь цикл while.
Я так понял, есть функция interval, принимающая в качестве аргумента любую другую функцию, которая и выполняется.. Но мне не это нужно, ведь тогда программа будет выполняться вечно? Или нет? %)
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Решено: qt4 "сброс буфера" [решено]
Так QTimer это не контрол. Просто создаёте объект этого типа, вот пример из хелпа:
PS для остановки просто в методе вызываете timer->stop(); если наступило условие. Вот и всё.
Код: Выделить всё
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
PS для остановки просто в методе вызываете timer->stop(); если наступило условие. Вот и всё.
Спасибо сказали:
-
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Решено: qt4 "сброс буфера" [решено]
NickLion писал(а): ↑24.12.2009 12:37Так QTimer это не контрол. Просто создаёте объект этого типа, вот пример из хелпа:
Код: Выделить всё
QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(update())); timer->start(1000);
PS для остановки просто в методе вызываете timer->stop(); если наступило условие. Вот и всё.
Если некритична точность таймера, то лучше сделать так:
Код: Выделить всё
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->setSingleShot(true);
timer->setInterval(1000);
timer->start();
И вызывать в слоте timer->start(); если нужно продолжать.
Спасибо сказали:
-
- Сообщения: 2579
Re: Решено: qt4 "сброс буфера" [решено]
А, кажется, понял. При выполнении функции start() программа не зависает на ней, как на sleep, а как бы выполняет команду в фоне. Попробую сегодня прикрутить.
-
- Сообщения: 862
- Статус: Адепт Дзен.
- ОС: Mint, Win7.
Re: Решено: qt4 "сброс буфера" [решено]
QTimerEvent, QObject::timerEvent(), QObject::startTimer(), QObject::killTimer().
Desipere in loco
Спасибо сказали:
-
- Сообщения: 2579
Re: Решено: qt4 "сброс буфера" [решено]
С таймером вроде бы разобрался. Всё работает, как надо. Запускается по timer->start()
Но вот как его остановить - не пойму. Мне нужно его остановить ровно тогда, когда значение переменной-счётчика станет нулевым.
Удобно было бы это сделать прямо из слота - но не получается обратиться к объекту timer - он его не видит.
Вот код:
В общем, как мне его остановить правильно?
Но вот как его остановить - не пойму. Мне нужно его остановить ровно тогда, когда значение переменной-счётчика станет нулевым.
Удобно было бы это сделать прямо из слота - но не получается обратиться к объекту timer - он его не видит.
Вот код:
Код: Выделить всё
#include "widget.h"
#include "ui_widget.h"
#include <cmath>
#include <QTimer>
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::update_onclicked() {
double q = ui->LeftProbability->text().toFloat();
double p = ui->RightProbability->text().toFloat();
int i = ui->CurrentPoint->text().toInt();
int l = ui->LeftPoint->text().toInt();
int r = ui->RightPoint->text().toInt();
double u = (pow(q/p,i)-pow(q/p,r-l))/(1-pow(q/p,r-l));
ui->ResultLabel->setText(QString::number(u));
QTimer *timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(update_timeout()));
timer->setInterval(1000);
timer->stop();
timer->start();
}
void Widget::update_timeout() {
double r=random()/(RAND_MAX+0.);
int i = ui->CurrentPoint->text().toInt();
double q = ui->LeftProbability->text().toFloat();
if (r<=q) ui->CurrentPoint->setText(QString::number(--i));
if (r>q) ui->CurrentPoint->setText(QString::number(++i));
ui->horizontalSlider->setValue(i);
// эта строка не работает
if (i==0) timer->stop();
}
void Widget::update_onchanged() {
int c = ui->CurrentPoint->text().toInt();
int l = ui->LeftPoint->text().toInt();
int r = ui->RightPoint->text().toInt();
ui->horizontalSlider->setMinimum(l);
ui->horizontalSlider->setMaximum(r);
ui->horizontalSlider->setValue(c);
}
void Widget::update_property_left() {
double l = ui->LeftProbability->text().toDouble();
if (l<=1) ui->RightProbability->setText(QString::number(1-l));
}
void Widget::update_property_right() {
double r = ui->RightProbability->text().toDouble();
if (r<=1) ui->LeftProbability->setText(QString::number(1-r));
}
В общем, как мне его остановить правильно?
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Решено: qt4 "сброс буфера" [решено]
Сделайте так, чтобы было видно из слота - QTimer *timer; поместите в сам класс. А вот эту строку:
QTimer *timer = new QTimer(this);
уберите, а в конструктор
timer = new QTimer(this);
В деструктор:
delete timer;
QTimer *timer = new QTimer(this);
уберите, а в конструктор
timer = new QTimer(this);
В деструктор:
delete timer;
Спасибо сказали:
-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: Решено: qt4 "сброс буфера" [решено]
Кстати - у QT есть функции принудительного запуска обработки очереди событий.
Если не ошибаюсь это QEventLoop::processEvents()
Я примерно в таком нахальном стиле делал "синхронный" способ работы с ком-портами.
сначала Sleep(), потом принудительная обработка сообщений, а после анализ чего-же нам там понаприсылали.
Если не ошибаюсь это QEventLoop::processEvents()
Я примерно в таком нахальном стиле делал "синхронный" способ работы с ком-портами.
сначала Sleep(), потом принудительная обработка сообщений, а после анализ чего-же нам там понаприсылали.
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
-
- Сообщения: 2579
Re: Решено: qt4 "сброс буфера" [решено]
Во-во, ага, я про неё, видимо, и спрашивал в первом посте. Но да, не стоит, лучше таймер - он как раз для того, что мне нужно.
Это-то я понял. Но не пойму, как сие сделать. %) Это уже не про куте4 вопрос, а скорее про с++.
Просто определить его как свойство класса Widget, вписать в заголовочный файл, так? =)
Сейчас попробую...
-
- Сообщения: 2579
Re: Решено: qt4 "сброс буфера" [решено]
Всё! получилось. =) Огромный пряник всем.
-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: Решено: qt4 "сброс буфера" [решено]
Иного выхода не было))) надо было минимальными усилиями обеспечить синхронное взаимодействие между объектами которые общались посредством сигналов и слотов. ))))
-
- Сообщения: 862
- Статус: Адепт Дзен.
- ОС: Mint, Win7.
Re: Решено: qt4 "сброс буфера" [решено]
А настолько ли был нужен механизм сигналов и слотов? Он ведь более высокооуровневый событий.
Desipere in loco
-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: Решено: qt4 "сброс буфера" [решено]
ну в общем да. хотел сделать элементы системы "максимально развязанными". Вплоть до того, чтобы исходная система знала только том , что на том конце - "какой-то потомоr QObject", который даже не понятно откуда взялся.
или я не понял вашего вопроса....
-
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Решено: qt4 "сброс буфера" [решено]
А почему бы не реализовать операции ввода-вывода в отдельном потоке?
-
- Сообщения: 862
- Статус: Адепт Дзен.
- ОС: Mint, Win7.
Re: Решено: qt4 "сброс буфера" [решено]
Это я про конкретный пример спрашивал. Я понимаю когда один сигнал обрабатывается несколькими объектами.
Но когда любой потомок от QObject имеет возможность создавать свой таймер, и обрабатывать событие по этому таймеру, то зачем плодить лишние объекты?
Desipere in loco
-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: Решено: qt4 "сброс буфера" [решено]
RasenHerz писал(а): ↑26.12.2009 19:47
А почему бы не реализовать операции ввода-вывода в отдельном потоке?
Они в отдельном потоке и крутились. т.е. там крутился транспортный класс.
Но когда вам надо сделать в классе реализующем логику протокола более высокого уровня - например серию запрос-ответ-запрос2-ответ2 - что бы не "городить огород" с кучей состояний и усложнением логики в обработчиках - а реализовать всю транзакцию сразу в одной процедуре - то это "самое то".
-
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Решено: qt4 "сброс буфера" [решено]
Denjs писал(а): ↑26.12.2009 19:57Они в отдельном потоке и крутились. т.е. там крутился транспортный класс.
Но когда вам надо сделать в классе реализующем логику протокола более высокого уровня - например серию запрос-ответ-запрос2-ответ2 - что бы не "городить огород" с кучей состояний и усложнением логики в обработчиках - а реализовать всю транзакцию сразу в одной процедуре - то это "самое то".
Я имел ввиду асинхронное обновление GUI, чтобы не было необходимости принудительно запускать цикл обработки сообщений во время длительных во времени операций.