1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/zlgopen-awtk

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
how_to_non_gui_thread_operate_widget.md 5.6 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 28.11.2024 22:52 91e8897

Как работать с GUI-компонентами из не-GUI потока

GUI-компоненты можно использовать только в GUI потоке. Чтобы работать с ними из не-GUI потока, необходимо применить последовательную обработку.

1. idle_queue

idle_queue отправляет запрос на добавление idle в очередь событий главного цикла GUI потока. Главный цикл GUI потока помещает функцию idle в менеджер idle при обработке очереди событий. При распределении idle функция idle выполняется в GUI потоке.

/**
 * @method idle_queue
 * Используется для добавления idle из не-GUI потока. Эта функция отправляет запрос на увеличение idle в очередь событий основного цикла.
 * @annotation ["static"]
 * @param {idle_func_t} on_idle Функция обратного вызова idle.
 * @param {void*} ctx Контекст функции обратного вызова idle.
 *
 * @return {ret_t} Возвращает RET_OK в случае успеха, иначе — ошибку.
 */
ret_t idle_queue(idle_func_t on_idle, void* ctx);

Если функция on_idle возвращает RET_REPEAT, она будет выполнена повторно.

2. timer_queue

timer_queue отправляет запрос на добавление таймера в очередь событий главного цикла GUI потока. Главный цикл GUI потока помещает функцию таймера в менеджер таймеров при обработке очереди событий. Когда таймер распределяется, функция таймера выполняется в GUI потоке.

/**
 * @method timer_queue
 * Используется для добавления таймера из не-GUI потока. Эта функция отправляет запрос на увеличение таймера в очередь событий основного цикла.
 * @annotation ["static"]
 * @param {timer_func_t} on_timer Функция обратного вызова таймера. Если функция обратного вызова возвращает RET_REPEAT, то она будет выполняться повторно. В противном случае она автоматически удаляется.
 * @param {void*} ctx Контекст функции обратного вызова таймера.
 * @param {uint32_t} duration Время.
 *
 * @return {ret_t} Возвращает RET_OK в случае успеха, иначе — ошибку.
 */
ret_t timer_queue(timer_func_t on_timer, void* ctx, uint32_t duration);

3. tk_run_in_ui_thread

tk_run_in_ui_thread позволяет фоновому потоку выполнять указанную функцию в UI потоке. Это оболочка для idle_queue, которая поддерживает ожидание завершения вызова.

/**
 * @method tk_run_in_ui_thread
 * Выполняет указанную функцию в потоке UI.
 *
 * @param {tk_callback_t} func Функция.
 * @param {void*} ctx  Контекст функции.
 * @param {bool_t} wait_until_done Ожидать ли завершения.
 *
 * @return {ret_t} Возвращает RET_OK в случае успеха, иначе — ошибку.
 */
ret_t tk_run_in_ui_thread(tk_callback_t func, void* ctx, bool_t wait_until_done)

Если wait_until_done имеет значение FALSE, и функция func возвращает RET_REPEAT, функция будет выполнена повторно.

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

Пример:

void* test_thread1(void* args) {
  int nr = 500000;
  while ((nr-- > 0) && (!s_app_quit)) {
    tk_run_in_ui_thread((tk_callback_t)update_progress_bar, args, TRUE);
    sleep_ms(30);
  }

  return NULL;
}

void* test_thread2(void* args) {
  int nr = 500000;
  while ((nr-- > 0) && (!s_app_quit)) {
    tk_run_in_ui_thread((tk_callback_t)update_progress_bar, args, FALSE);
    sleep_ms(30);
  }

  return NULL;
}

static ret_t on_idle(const idle_info_t* idle) {
  return update_progress_bar(WIDGET(idle->ctx));
}

void* test_thread3(void* args) {
  int nr = 500000;
  while ((nr-- > 0) && (!s_app_quit)) {
    idle_queue(on_idle, args);
    sleep_ms(30);
  }

  return NULL;
}

static ret_t on_timer(const timer_info_t* timer) {
  return update_progress_bar(WIDGET(timer->ctx));
}

void* test_thread4(void* args) {
  int nr = 500000;
  while ((nr-- > 0) && (!s_app_quit)) {
    timer_queue(on_timer, args, 30);
    sleep_ms(30);
  }

  return NULL;
}

Примечание:

  • Во время выполнения функции idle окно может быть уже закрыто, а компоненты могут находиться в недопустимом состоянии. Чтобы избежать проблем с указателями, в функции idle следует проверять, существуют ли целевое окно и компонент.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/zlgopen-awtk.git
git@api.gitlife.ru:oschina-mirror/zlgopen-awtk.git
oschina-mirror
zlgopen-awtk
zlgopen-awtk
master