Решено: qt4 "сброс буфера" [решено] (или как подружить со sleep)

Модератор: Модераторы разделов

Flaming
Сообщения: 2579

Решено: qt4 "сброс буфера" [решено]

Сообщение Flaming »

Есть задачка такая. Раз в секунду менять значение какого-то объекта. Например, это ползунок, его нужно каждую секунду куда-то сдвигать, влево или вправо...
Как сдвигать вообще, я разобрался. Создал цикл while. В него вписал команды, которые собственно управляют свойствами, и sleep(1).

Так вот, это всё не работает. Причём программа ещё и намертно зависает при этом. Но не насовсем. А на общее количество секунд простаивания. То есть если цикл while выполнялся 10 раз, то и "спать" программа будет 10 секунд. И потом ползунок сразу сдвинется куда надо за все 10 шагов за один момент (а не пошагово, по одному движению в секунду). А мне надо чтобы он постепенно двигался, плавно.

Провёл эксперимент. Создал консольную программу, которая выводит случайные значения на экран и опять же использует sleep. Если просто после каждого вывода значения вписать функцию sleep(1) - такой же эффект, как в предыдущей задаче. Пишет всё и сразу - но при самом завершении программы.
Если же "поправить" вывод программы, добавив std::flush после каждого std::cout, то выводится нормально, как надо. Потому что сбрасываетя буфер.

В общем, вопрос такой, как сбросить такой же буфер в qt4? Что нужно написать, чтобы все изменения, которые я произвёл со значениями, применились?
Спасибо сказали:
pcodr
Сообщения: 283
ОС: Debian

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение pcodr »

Забудьте про sleep. Используйте таймер.
remote system type is unix
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение RasenHerz »

Использовать sleep в основном потоке графического приложения нельзя - вы останавливаете разбор очереди событий и программа "зависает". Как уже говорилось, используйте QTimer.
Спасибо сказали:
Flaming
Сообщения: 2579

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Flaming »

Ммм, я так и думал. Спасибо, что разъяснили.
А можно ли прикрутить qtimer через qt desighner? А то всю форму через него делал... там и компоновать довольно удобно. А то не нашёл такого компонента на палитрах... Помню, в дельфи был такой компонент timer - он именно так и прицеплялся. А тут, видимо, по-другому.
Спасибо сказали:
Flaming
Сообщения: 2579

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Flaming »

Ладно, с этим может всё равно потом разберусь... Сейчас разобраться, как вообще таймером пользоваться. Где там функция засыпания?
Мне просто надо выполнить одну и ту же операцию неизвестное количество раз, пока не выполнится какое-то условие. То бишь цикл while.
Я так понял, есть функция interval, принимающая в качестве аргумента любую другую функцию, которая и выполняется.. Но мне не это нужно, ведь тогда программа будет выполняться вечно? Или нет? %)
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение NickLion »

Так QTimer это не контрол. Просто создаёте объект этого типа, вот пример из хелпа:

Код: Выделить всё

     QTimer *timer = new QTimer(this);
     connect(timer, SIGNAL(timeout()), this, SLOT(update()));
     timer->start(1000);



PS для остановки просто в методе вызываете timer->stop(); если наступило условие. Вот и всё.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение RasenHerz »

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(); если нужно продолжать.
Спасибо сказали:
Flaming
Сообщения: 2579

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Flaming »

А, кажется, понял. При выполнении функции start() программа не зависает на ней, как на sleep, а как бы выполняет команду в фоне. Попробую сегодня прикрутить.
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Crazy »

QTimerEvent, QObject::timerEvent(), QObject::startTimer(), QObject::killTimer().

Desipere in loco
Спасибо сказали:
Flaming
Сообщения: 2579

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Flaming »

С таймером вроде бы разобрался. Всё работает, как надо. Запускается по timer->start()
Но вот как его остановить - не пойму. Мне нужно его остановить ровно тогда, когда значение переменной-счётчика станет нулевым.
Удобно было бы это сделать прямо из слота - но не получается обратиться к объекту 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));
}


В общем, как мне его остановить правильно?
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение NickLion »

Сделайте так, чтобы было видно из слота - QTimer *timer; поместите в сам класс. А вот эту строку:
QTimer *timer = new QTimer(this);
уберите, а в конструктор
timer = new QTimer(this);
В деструктор:
delete timer;
Спасибо сказали:
Аватара пользователя
Denjs
Сообщения: 1685
ОС: SuSe 10.2

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Denjs »

Кстати - у QT есть функции принудительного запуска обработки очереди событий.
Если не ошибаюсь это QEventLoop::processEvents()
Я примерно в таком нахальном стиле делал "синхронный" способ работы с ком-портами.
сначала Sleep(), потом принудительная обработка сообщений, а после анализ чего-же нам там понаприсылали.
QDroid - Среда исполнения и фреймворк для QtScript.
OTPD - Открытые драйвера промышленных принтеров чеков и этикеток (кроссплатформенная подсистема печати).
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение NickLion »

Denjs писал(а):
25.12.2009 14:20
Я примерно в таком нахальном стиле

Именно нахальном... Не стоит так писать. Это если срочно и программа больше не понадобится.
Спасибо сказали:
Flaming
Сообщения: 2579

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Flaming »

Denjs писал(а):
25.12.2009 14:20
Кстати - у QT есть функции принудительного запуска обработки очереди событий.
Если не ошибаюсь это QEventLoop::processEvents()

Во-во, ага, я про неё, видимо, и спрашивал в первом посте. Но да, не стоит, лучше таймер - он как раз для того, что мне нужно.
NickLion писал(а):
25.12.2009 14:04
Сделайте так, чтобы было видно из слота - QTimer *timer; поместите в сам класс.

Это-то я понял. Но не пойму, как сие сделать. %) Это уже не про куте4 вопрос, а скорее про с++.
Просто определить его как свойство класса Widget, вписать в заголовочный файл, так? =)

Сейчас попробую...
Спасибо сказали:
Flaming
Сообщения: 2579

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Flaming »

Всё! получилось. =) Огромный пряник всем.
Спасибо сказали:
Аватара пользователя
Denjs
Сообщения: 1685
ОС: SuSe 10.2

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Denjs »

NickLion писал(а):
25.12.2009 14:25
Denjs писал(а):
25.12.2009 14:20
Я примерно в таком нахальном стиле

Именно нахальном... Не стоит так писать. Это если срочно и программа больше не понадобится.

Иного выхода не было))) надо было минимальными усилиями обеспечить синхронное взаимодействие между объектами которые общались посредством сигналов и слотов. ))))
QDroid - Среда исполнения и фреймворк для QtScript.
OTPD - Открытые драйвера промышленных принтеров чеков и этикеток (кроссплатформенная подсистема печати).
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Crazy »

А настолько ли был нужен механизм сигналов и слотов? Он ведь более высокооуровневый событий.

Desipere in loco
Спасибо сказали:
Аватара пользователя
Denjs
Сообщения: 1685
ОС: SuSe 10.2

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Denjs »

Crazy писал(а):
26.12.2009 18:18
А настолько ли был нужен механизм сигналов и слотов? Он ведь более высокооуровневый событий.

ну в общем да. хотел сделать элементы системы "максимально развязанными". Вплоть до того, чтобы исходная система знала только том , что на том конце - "какой-то потомоr QObject", который даже не понятно откуда взялся.

или я не понял вашего вопроса....
QDroid - Среда исполнения и фреймворк для QtScript.
OTPD - Открытые драйвера промышленных принтеров чеков и этикеток (кроссплатформенная подсистема печати).
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение RasenHerz »

Denjs писал(а):
26.12.2009 18:44
Crazy писал(а):
26.12.2009 18:18
А настолько ли был нужен механизм сигналов и слотов? Он ведь более высокооуровневый событий.

ну в общем да. хотел сделать элементы системы "максимально развязанными". Вплоть до того, чтобы исходная система знала только том , что на том конце - "какой-то потомоr QObject", который даже не понятно откуда взялся.

или я не понял вашего вопроса....

А почему бы не реализовать операции ввода-вывода в отдельном потоке?
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Crazy »

Denjs писал(а):
26.12.2009 18:44
Crazy писал(а):
26.12.2009 18:18
А настолько ли был нужен механизм сигналов и слотов? Он ведь более высокооуровневый событий.

ну в общем да. хотел сделать элементы системы "максимально развязанными". Вплоть до того, чтобы исходная система знала только том , что на том конце - "какой-то потомоr QObject", который даже не понятно откуда взялся.

или я не понял вашего вопроса....

Это я про конкретный пример спрашивал. Я понимаю когда один сигнал обрабатывается несколькими объектами.
Но когда любой потомок от QObject имеет возможность создавать свой таймер, и обрабатывать событие по этому таймеру, то зачем плодить лишние объекты?

Desipere in loco
Спасибо сказали:
Аватара пользователя
Denjs
Сообщения: 1685
ОС: SuSe 10.2

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение Denjs »

RasenHerz писал(а):
26.12.2009 19:47
Denjs писал(а):
26.12.2009 18:44
Crazy писал(а):
26.12.2009 18:18
А настолько ли был нужен механизм сигналов и слотов? Он ведь более высокооуровневый событий.

ну в общем да. хотел сделать элементы системы "максимально развязанными". Вплоть до того, чтобы исходная система знала только том , что на том конце - "какой-то потомоr QObject", который даже не понятно откуда взялся.

или я не понял вашего вопроса....

А почему бы не реализовать операции ввода-вывода в отдельном потоке?

Они в отдельном потоке и крутились. т.е. там крутился транспортный класс.
Но когда вам надо сделать в классе реализующем логику протокола более высокого уровня - например серию запрос-ответ-запрос2-ответ2 - что бы не "городить огород" с кучей состояний и усложнением логики в обработчиках - а реализовать всю транзакцию сразу в одной процедуре - то это "самое то".
QDroid - Среда исполнения и фреймворк для QtScript.
OTPD - Открытые драйвера промышленных принтеров чеков и этикеток (кроссплатформенная подсистема печати).
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Решено: qt4 "сброс буфера" [решено]

Сообщение RasenHerz »

Denjs писал(а):
26.12.2009 19:57
Они в отдельном потоке и крутились. т.е. там крутился транспортный класс.
Но когда вам надо сделать в классе реализующем логику протокола более высокого уровня - например серию запрос-ответ-запрос2-ответ2 - что бы не "городить огород" с кучей состояний и усложнением логики в обработчиках - а реализовать всю транзакцию сразу в одной процедуре - то это "самое то".

Я имел ввиду асинхронное обновление GUI, чтобы не было необходимости принудительно запускать цикл обработки сообщений во время длительных во времени операций.
Спасибо сказали: