QT Repaint / Redraw / Update / Do Something - PullRequest
20 голосов
/ 13 января 2010

Я новичок в QT. Я понимаю, что вы можете принудительно обновить экран, но я выдернул все волосы, пытаясь понять, как это сделать. Вот что я специально пытаюсь сделать.

Я нажимаю кнопку (событие сигнала onClick), которая запускает код, который изменяет изображение (QLabel) на дисплее, ждет ввода и затем выполняет изменение нового изображения (другой QLabel). Я перепробовал все, и дисплей не обновляется, пока не завершится код события сигнала onclick. Сейчас я не жду ввода пользователя, я использую usleep (~ 500 мс) для тестирования.

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

Как заставить принудительно обновить растровое изображение QLabel. Я перепробовал все. Ниже приведен весь код, который я пробовал в своем обработчике сигнала onClick. (upButton - это имя QLabel, представляющего собой растровое изображение)

update();
repaint();
ui->upButton->setUpdatesEnabled(TRUE);
update();
repaint();
QPaintEvent paintevent(ui->upButton->childrenRegion());
QPaintEvent * test = &paintevent;
paintEvent(test);
this->changeEvent(test);
ui->upButton->update();
ui->upButton->repaint();
ui->upButton->repaint(ui->upButton->childrenRegion());
repaint();
QApplication::sendPostedEvents();
this->parentWidget()->update();
usleep(100000);

Как видите, сейчас я просто стреляю в темноте. Я попытался посмотреть пример кода и сделать всю домашнюю работу, но я заблудился. Цени любую помощь, совет и / или пример кода.

Ответы [ 4 ]

22 голосов
/ 14 января 2010

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

Как я уже говорил в своем вопросе, я не хотел использовать события, потому что это слишком много ненужной работы, чтобы выполнить что-то чрезвычайно просто.

Кроме того, «событие», которое должно иметь место для продолжения программы, является событием USB. Поскольку я использую устройство класса HID, невозможно установить событие без цикла ожидания. Классы USB HID не позволяют устанавливать прерывания, ОС утверждает, что устройство.

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

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

qApp->processEvents();

qApp - это глобальная внешняя переменная в заголовке QApplication.

Поскольку это событие USB усложняет мой поток, я наткнулся на класс QWaitCondition. Я собирался начать процесс в ожидании события USB. Я бы подождал, пока процесс освободит условие ожидания для продолжения моей процедуры.

Но если кто-то думает, что это плохая идея, пожалуйста, высказывайтесь. Я действительно ценю ваши отзывы PiedPiper и Hostile Fork.

Спасибо.

7 голосов
/ 13 января 2010

Вы не должны ждать ввода в вашем обработчике событий. Вам необходимо переосмыслить логику вашей программы, чтобы использовать события так, как они были предназначены. Все вызовы update () и repaint () в вашем коде не нужны, если вы вернетесь в цикл обработки событий.

5 голосов
/ 02 февраля 2015

Иногда я замечал, что когда у вас есть многоуровневые виджеты или виджеты внутри виджетов, это помогает вызывать их события repaint ().

Например

this->repaint();
this->parentWidget()->repaint();
this->parentWidget()->parentWidget()->repaint();

Это гораздо проще, чем отправить любую обработку в другой поток или создать дополнительные обработчики событий.

2 голосов
/ 20 января 2010

Если я правильно понял, у вас есть слот, и в этом слоте вы обновляете изображение, показанное в QLabel. Но вы хотите, чтобы это изменение отображалось до завершения слота.

В этом случае выполните событие update () и вызовите qApp-> processEvents (). Этот метод обрабатывает события, ожидающие в очереди событий, а затем возвращает их, поэтому это может быть тем, что вам нужно.

PS: обновление () может вообще не понадобиться, я не уверен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...