Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Qt и кроссплатформенное программирование С/С++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.11.2018, 16:02   #1
Yudin
Пользователь
 
Регистрация: 11.01.2018
Сообщений: 49
Восклицание Бесконечная функция с изменяющемся вне неё параметром

Здравствуйте. Мне нужно реализовать бесконечную функцию, в которой есть параметр, который может изменяться вне неё.
Например:

Код:
cleaner->setDelay(7);

while (cleaner->ON == true)
        cleaner->getRubbish(cleaner->getDelay());


getRubbish(int delay)
{
            srand (time(NULL));
            rubbish = 1 + rand() % 2;
            Sleep(delay);
            return rubbish;
}
Я это делаю в qt, и у меня будет кнопка изменения мощности, которая и будет отвечать за изменение delay (эмуляция мощности). То есть надо сделать так, чтобы ИЗМЕНИТЬ DELAY МОЖНО БЫЛО В ХОДЕ ВЫПОЛНЕНИЯ ПРОГРАММЫ, но функция getRubbish() никогда не должна прерваться, она должна постоянно работать с delay, который МОЖЕТ измениться в ходе выполнения.
Если я выполню код, который написал выше, то при входе в цикл программа зависает, что и очевидно. Цикл выполняется бесконечно и ему по-барабану, хочу ли я изменить delay или нет, он принял начальное значение delay и работает с ним бесконечно.
Как мне это исправить? Я думаю, что надо прибегнуть к параллельному выполнению, но не совсем в этом разбираюсь. Если это так, напишите минимальный код, пожалуйста.
Yudin вне форума Ответить с цитированием
Старый 01.12.2018, 15:09   #2
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

Для многопоточности в Qt, есть класс QThread. В его методе run(), код выполняется в отдельном потоке.
Для этого нужно создать свой класс и переопределить, в нем метод run().
Код:
class MyThread public QThread
{
    Q_OBJECT

public:
    MyThread(QObject *parent = 0) : QThread(parent)
    {}

    void run()
    {
         // Сюда вставь свой бесконечный цикл
    }
};
Использование класса
Код:
MyThread *thread = new MyThread(); // Сюда можешь передать this

// Запускаем поток
thread->start();
Это лишь один из способов использования QThread. Можно обойтись и без наследования, использовать QThread на прямую.

В общем гугли.

вот несколько ссылок на видео:
https://youtu.be/ez0_PjTb8Zk?list=PL...aac6jYqRZk3jbm
https://youtu.be/XwS_LBHmvzU?list=PL...aac6jYqRZk3jbm
https://youtu.be/wEdFLeT6fPw?list=PL...aac6jYqRZk3jbm

Вообще твоя задача не совсем понятна. Возможно можно обойтись без бесконечного цикла. Используя сигналы и слоты.

Последний раз редактировалось SAMOUCHKA; 01.12.2018 в 15:19.
SAMOUCHKA вне форума Ответить с цитированием
Старый 01.12.2018, 16:11   #3
Yudin
Пользователь
 
Регистрация: 11.01.2018
Сообщений: 49
По умолчанию

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
Для этого нужно создать свой класс и переопределить, в нем метод run().
Спасибо за ваш ответ. Я уже сам тоже дошёл до этого варианта, но мне он кажется не совсем правильным, потому что мне ведь надо передать всего лишь одну функцию, а так получается я передаю весь объект (но у меня ведь в нём и другие функции, которым нет необходимости работать в другом потоке!). Да и получается я делаю наследование, если мне не хватает функционала класса родителя, а в моём случае это ведь не совсем так. Я хотел бы передать в новый поток только одну функцию. Короче говоря, этот вариант мне кажется немного "куцым"...

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
Вообще твоя задача не совсем понятна. Возможно можно обойтись без бесконечного цикла. Используя сигналы и слоты.
У меня есть пылесос. В нём есть функции: getRubbish() - работает до тех пор пока не нажата кнопка "Выкл" (но пусть пока она будет бесконечной), setPower() - изменение мощности. Нажимаю кнопку "Вкл", запускается функция getRubbish() с бесконечным циклом, которая выполняет некое действие. Но эта функция внутри себя использует переменную POWER, которую пользователь может менять в ходе работы (после нажатия кнопки "Вкл"), нажимая кнопку "Изменить мощность" (вызывается слот, в котором вызывается функция setPower()). И вот теперь у меня вопрос. У меня ведь две эти функции находятся в одном объекте, и в новый поток я передаю этот объект. Так что получается, эти функции находятся в одном потоке? В run() я описал ф-ию с бесконечным циклом getRubbish().

Код:
motor = new Motor;
QThread th1(motor);

connect(onOFF, &QAbstractButton::clicked, this, &MainWindow::slotOnOffPower);
connect(setPower, &QAbstractButton::clicked, this, &MainWindow::slotSetPower);

void MainWindow::slotSetPower() {
    bool ok = true;
    int item = QInputDialog::getInt(this, "Мощность", "Выберите", 0, 25, 100, 25, &ok);
    if(ok) {
        motor->setPower(item);
        if (motor->getPower() == 25)
            motor->setDelay(7000); //delay - задержка, нужна для эмуляции мощности пылесоса
        else if (motor->getPower() == 50)
            motor->setDelay(5000);
        else if (motor->getPower() == 75)
            motor->setDelay(3000);
        else motor->setDelay(1000);
    }
}

void MainWindow::slotOnOffPower()
{
    if (motor->ON)
        motor->ON = false;
    else {
        motor->ON = true;
        motor->start(); //по умолчанию delay = 3000
 }
}

void Motor::run()
{
    while (true) {
        srand (time(NULL));
        rubbish = 1 + rand() % 2;
        Sleep(delay);
    }
}
Yudin вне форума Ответить с цитированием
Старый 01.12.2018, 16:29   #4
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

Все равно не понятно для чего цикл, НО если без него ни как, можно использовать таймер.

создаем слот. он будет циклично вызываться
Код:
public slots:
    void slotOnTimeout()
    {
         // Код который был в цикле
    }
Код:
QTimer *timer = new QTimer(); // Сюда можешь передать this
connect(timer, SIGNAL(timeout()), this, SLOT(slotOnTimeout()));

timer->start(100);
Теперь у тебя раз в 100 миллисекунд будет вызываться слот slotOnTimeout(). То есть как бы аналог бесконечного цикла. И все работает в одном потоке.
SAMOUCHKA вне форума Ответить с цитированием
Старый 01.12.2018, 17:13   #5
Yudin
Пользователь
 
Регистрация: 11.01.2018
Сообщений: 49
По умолчанию

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
Все равно не понятно для чего цикл
Цикл это эмуляция работы пылесоса. Нажал кнопку "Вкл" и собирается мусор бесконечно. Там генерируется число от одного до двух, но это мне в дальнейшем нужно будет, сейчас неважно. Можно и не цикл, если есть альтернативы.

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
timer->start(100);

Теперь у тебя раз в 100 миллисекунд будет вызываться слот slotOnTimeout().
Всё, разобрался, спасибо огромное. Я боялся что не смогу изменить время таймера, не приостанавливая генерацию чисел, но всё работает. Не знал, что можно обойтись и без потоков. Ещё раз большое спасибо, что ответили, я бы не разобрался. Прикрепляю код, тема закрыта.

Код:
connect(onOFF, &QAbstractButton::clicked, this, &MainWindow::slotOnOffPower);
connect(setPower, &QAbstractButton::clicked, this, &MainWindow::slotSetPower);
connect(timer, SIGNAL(timeout()), this, SLOT(slotOnTimeout()));

void MainWindow::slotSetPower() {
    bool ok = true;
    int item = QInputDialog::getInt(this, "Мощность", "Выберите", 0, 25, 100, 25, &ok);
    if(ok) {
        motor->setPower(item);
        if (motor->getPower() == 25)
            motor->setDelay(7000);
        else if (motor->getPower() == 50)
            motor->setDelay(5000);
        else if (motor->getPower() == 75)
            motor->setDelay(3000);
        else motor->setDelay(1000);
        timer->start(motor->getDelay());
    }
}

void MainWindow::slotOnOffPower()
{
    if (motor->ON)
        motor->ON = false;
    else {
        motor->ON = true;
        slotSetPower();
    }
}

void MainWindow::slotOnTimeout()
{
    motor->getRubbish();
    QString s = QString::number(motor->rubbish);
    label->setText(s);
}
Yudin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема: Ссумирование зачений в изменяющемся количестве столбцов. ДмитрийТТ Microsoft Office Access 4 08.08.2014 13:27
Хэш Функция с параметром "Void" Fonduee Общие вопросы C/C++ 5 13.11.2013 12:06
Не работает функция: Найти ссылку с определённым текстом и нажать на неё(WB). rok_9 Помощь студентам 0 10.11.2012 20:58
БЕСКОНЕЧНАЯ СУММА Ania Lunee Помощь студентам 4 17.05.2012 22:41
Функция с параметром диапазоном savraska Microsoft Office Excel 5 26.05.2010 13:35