Подтвердить что ты не робот

Как создать функцию pause/wait с помощью Qt?

Я играю с Qt, и я хочу создать простую паузу между двумя командами. Однако, похоже, я не буду использовать Sleep(int mili);, и я не могу найти никаких очевидных функций ожидания.

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

4b9b3361

Ответ 1

В этом предыдущем вопросе упоминается использование qSleep(), которое находится в модуле QtTest. Чтобы избежать привязки служебных данных в модуле QtTest, глядя на источник этой функции, вы можете просто создать свою собственную копию и вызвать ее. Он использует определения для вызова Windows Sleep() или Linux nanosleep().

#ifdef Q_OS_WIN
#include <windows.h> // for Sleep
#endif
void QTest::qSleep(int ms)
{
    QTEST_ASSERT(ms > 0);

#ifdef Q_OS_WIN
    Sleep(uint(ms));
#else
    struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
    nanosleep(&ts, NULL);
#endif
}

Ответ 2

Я написал суперпростую функцию задержки для приложения, которое я разработал в Qt.

Я бы посоветовал вам использовать этот код, а не функцию сна, поскольку он не позволит вашему графическому интерфейсу заморозить.

Вот код:

void delay()
{
    QTime dieTime= QTime::currentTime().addSecs(1);
    while (QTime::currentTime() < dieTime)
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}

Чтобы задержать событие на n секунд - используйте addSecs(n).

Ответ 4

Малый +1 до kshark27 answer, чтобы сделать его динамичным:

#include <QTime>

void delay( int millisecondsToWait )
{
    QTime dieTime = QTime::currentTime().addMSecs( millisecondsToWait );
    while( QTime::currentTime() < dieTime )
    {
        QCoreApplication::processEvents( QEventLoop::AllEvents, 100 );
    }
}

Ответ 5

Мы использовали ниже класс -

class SleepSimulator{
     QMutex localMutex;
     QWaitCondition sleepSimulator;
public:
    SleepSimulator::SleepSimulator()
    {
        localMutex.lock();
    }
    void sleep(unsigned long sleepMS)
    {
        sleepSimulator.wait(&localMutex, sleepMS);
    }
    void CancelSleep()
    {
        sleepSimulator.wakeAll();
    }
};

QWaitCondition предназначен для координации ожидания мьютекса между различными потоками. Но то, что делает эту работу, - метод ожидания имеет таймаут на нем. Когда он называется так, он функционирует точно так же, как функция сна, но он использует цикл событий Qt для синхронизации. Таким образом, никакие другие события или пользовательский интерфейс не блокируются, как функция нормальной работы Windows.

В качестве бонуса мы добавили функцию CancelSleep, чтобы другая часть программы отменила функцию "sleep".

Что нам понравилось в этом, так это то, что он легкий, многоразовый и полностью автономный.

QMutex: http://doc.qt.io/archives/4.6/qmutex.html

QWaitCondition: http://doc.qt.io/archives/4.6/qwaitcondition.html

Ответ 6

Поскольку вы пытаетесь "проверить некоторый код класса", я бы действительно рекомендовал учиться использовать QTestLib. Он предоставляет пространство имен QTest и модуль QtTest, который содержат ряд полезных функций и объектов, в том числе QSignalSpy, которые вы можете использовать для проверки того, что определенные сигналы испускаются.

Поскольку вы в конечном итоге будете интегрироваться с полным графическим интерфейсом, использование QTestLib и тестирование без сна или ожидания даст вам более точный тест - тот, который лучше отражает истинные шаблоны использования. Но, если вы решите не идти по этому маршруту, вы можете использовать QTestLib:: qSleep, чтобы выполнить то, что вы запросили.

Поскольку вам просто нужно сделать паузу между запуском насоса и его выключением, вы можете легко использовать таймер с одним выстрелом:

class PumpTest: public QObject {
    Q_OBJECT
    Pump &pump;
public:
    PumpTest(Pump &pump):pump(pump) {};
public slots:
    void start() { pump.startpump(); }
    void stop() { pump.stoppump(); }
    void stopAndShutdown() {
        stop();
        QCoreApplication::exit(0);
    }
    void test() {
        start();
        QTimer::singleShot(1000, this, SLOT(stopAndShutdown));
    }
};

int main(int argc, char* argv[]) {
    QCoreApplication app(argc, argv);
    Pump p;
    PumpTest t(p);
    t.test();
    return app.exec();
}

Но qSleep() определенно будет проще, если все, что вас интересует, это проверить пару вещей в командной строке.

РЕДАКТИРОВАТЬ. На основе комментариев здесь требуются шаблоны использования.

Сначала вам нужно отредактировать файл .pro, чтобы включить qtestlib:

CONFIG += qtestlib

Во-вторых, вам нужно включить необходимые файлы:

  • Для пространства имен QTest (которое включает qSleep): #include <QTest>
  • Для всех элементов в модуле QtTest: #include <QtTest>. Это функционально эквивалентно добавлению include для каждого элемента, который существует в пространстве имен.

Ответ 7

Чтобы использовать стандартную функцию сна, добавьте следующее в ваш .cpp файл:

#include <unistd.h>

Как и в Qt версии 4.8, доступны следующие функции сна:

void QThread::msleep(unsigned long msecs)
void QThread::sleep(unsigned long secs)
void QThread::usleep(unsigned long usecs)

Чтобы использовать их, просто добавьте следующее в ваш .cpp файл:

#include <QThread>

Ссылка: QThread (через документацию Qt): http://doc.qt.io/qt-4.8/qthread.html

В противном случае выполните следующие действия...

Измените файл проекта следующим образом:

CONFIG += qtestlib

Обратите внимание, что в новых версиях Qt вы получите следующую ошибку:

Project WARNING: CONFIG+=qtestlib is deprecated. Use QT+=testlib instead.

... поэтому, измените файл проекта следующим образом:

QT += testlib

Затем в вашем .cpp файле обязательно добавьте следующее:

#include <QtTest>

И затем используйте одну из функций сна так:

usleep(100);

Ответ 8

На протяжении многих лет у меня было много проблем, пытаясь заставить QApplication:: processEvents работать, как это используется в некоторых из лучших ответов. IIRC, если несколько адресов в конечном итоге вызвали его, это может привести к тому, что некоторые сигналы не будут обработаны (https://doc.qt.io/archives/qq/qq27-responsive-guis.html). Мой обычный предпочтительный вариант - использовать QEventLoop (https://doc.qt.io/archives/qq/qq27-responsive-guis.html#waitinginalocaleventloop).

inline void delay(int millisecondsWait)
{
    QEventLoop loop;
    QTimer t;
    t.connect(&t, &QTimer::timeout, &loop, &QEventLoop::quit);
    t.start(millisecondsWait);
    loop.exec();
}

Ответ 9

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

void MyClass::sleepFor(qint64 milliseconds){
    qint64 timeToExitFunction = QDateTime::currentMSecsSinceEpoch()+milliseconds;
    while(timeToExitFunction>QDateTime::currentMSecsSinceEpoch()){
        QApplication::processEvents(QEventLoop::AllEvents, 100);
    }
}

Ответ 10

Если вы хотите использовать кросс-платформенный метод для этого, общий шаблон должен быть получен из QThread и создать функцию (статическую, если хотите) в производном классе, которая вызовет одну из функций ожидания в QThread.

Ответ 11

Ответ @kshark27 у меня почему-то не сработал (потому что я использую Qt 5.7?), поэтому я закончил тем, что сделал это:

while (someCondition) {

   // do something

   QApplication::processEvents();
   QThread::sleep(1); // 1 second

};

Если это делается в потоке графического интерфейса, он, очевидно, вводит задержку в 1 секунду перед тем, как реагировать на пользовательские события. Но если вы можете с этим смириться, это решение, вероятно, проще всего реализовать, и даже Qt одобряет его в своей статье " Основы потоков" (см. Раздел " Когда использовать альтернативы потокам ").

Ответ 12

мы можем использовать следующий метод QT_Delay:

QTimer::singleShot(2000,this,SLOT(print_lcd()));

Это будет ждать 2 секунды перед вызовом print_lcd().