Страницы

Поиск по вопросам

пятница, 15 марта 2019 г.

Как сделать мигающее окно

Делаю сейчас программу, в которой второе окно должно мигать морзянкой сменяя черный фон белым. Я уже и через таймер попробовал в самом коде окна и в отдельный поток выкладывал. Сейчас у меня такой вариант(тестовый) и он не работает. Появляется белое окно, потом проходит время равное сумме всех интервалов таймера и потом окно становится черным, хотя задумка теста - окно должно мигать несколько раз с интервалом, заданным в таймере
for(int j = 0; j < 3; j++) { this->setPalette(QPalette(Qt::white)); this->show(); m_timer->start(2000); }
коннект для приема сигнала от таймера
QObject::connect(m_timer, SIGNAL(timeout()), this, SLOT(BlackWindow()));
и сам слот
void morzewindow::BlackWindow() { this->setPalette(QPalette(Qt::black)); this->show(); m_timer->stop(); }
Может у кого-то была подобная задача реализованная средствами Qt? помогите. Мне как новичку уже ни одной идеи в голову не приходит. Все что знал, о чем подозревал, все перепробовал.
UPDATE:
запуск потока и функции в нем:
MorzeBlinkTimer.moveToThread(&MorzeBlinkThread); QObject::connect(&MorzeBlinkTimer, SIGNAL(latency(bool)), SLOT(Blink(bool))); MorzeBlinkThread.start(); MorzeBlinkTimer.startBlink(etalon2.GetReadyCodeMorzeForBlink());
функцию запускаю вручную, потому что она принимает указатель на массив с морзянкой.
//слот для смены цвета окна морзянки черный/белый
void morzewindow::Blink(bool BlackWhite) { if(BlackWhite) { this->setPalette(QPalette(Qt::white)); this->show(); } else { this->setPalette(QPalette(Qt::black)); this->show(); } }
и сама функция потока, которая вводит задержку(фрагмент):
void startBlink(int* morze) { for(int i = 0; i < 50; i++) { switch(morze[i]) { case 0: emit latency(true); QThread::msleep(iDot); emit latency(false); QThread::msleep(iPauseSymbol); break; } } }


Ответ

Все правильно, пока все функции не отработают и не "встанут" в ожидании событий в графическом интерфейсе - он не обновится.
Делать надо отдельным потоком, но там есть тонкости, тоже долго получалось как у вас - что не реагировало окно ни на что, пока не отработают все события.
Вот рабочий пример обновления графического интерфейса в отдельном потоке.
В основной функции у вас должно быть примерено так:
//Starting process in the new thread Worker * pWorker = new Worker; QThread * pThread = new QThread(); pWorker->moveToThread(pThread); connect(pThread, SIGNAL(started()), pWorker, SLOT(slotDummyUpdatingRequest())); // сигнал старта потока соединяем с функцией имеющей задержки connect(pWorker, SIGNAL(sigDummyNextRequestStage()), this, SLOT(slotStageRequestPrint())); // сигнал от объекта осуществляющего задержки на обновление окна соединяем со слотом обновления окна текущего оъекта pThread->start();
И сам слот обновления графики, срабатывающий асинхронно:
void UpdatingRequestState::slotStageRequestPrint() { //здесь идет установка внешнего вида элементов, в моем случае используется QML QObject * pList = m_pQmlObject->findChild("requestList"); m_strListView.append(tr("requesting info...")); pList->setProperty("model", m_strListView); }
Ну и собственно функция, выполняемая в отдельном потоке, по сигналам которой интерфейс обновляется
void Worker::slotDummyUpdatingRequest() { //dummy imitation of the work for (int i = 0; i < 5; i++) { QThread::msleep(500); // задержка emit sigDummyNextRequestStage(); qDebug() << "Updating Request..."; } }

Комментариев нет:

Отправить комментарий